26

リフレクションの使用でパフォーマンスの問題が発生しています。
そこで、オブジェクトのプロパティのデリゲートを作成することにしました。これまでのところ、次のようになりました。

TestClass cwp = new TestClass();
var propertyInt = typeof(TestClass).GetProperties().Single(obj => obj.Name == "AnyValue");
var access = BuildGetAccessor(propertyInt.GetGetMethod());
var result = access(cwp);
static Func<object, object> BuildGetAccessor(MethodInfo method)
{
    var obj = Expression.Parameter(typeof(object), "o");

    Expression<Func<object, object>> expr =
        Expression.Lambda<Func<object, object>>(
            Expression.Convert(
                Expression.Call(
                    Expression.Convert(obj, method.DeclaringType),
                    method),
                typeof(object)),
            obj);

    return expr.Compile();
}

結果は非常に満足のいくもので、従来の方法を使用するよりも約 30 ~ 40 倍高速でした ( PropertyInfo.GetValue (obj, null);)

問題は、同じように機能するプロパティをどのように作成できるかということです。SetValue残念ながら、方法がありませんでした。

<T>アプリケーションの構造上、メソッドを使用できないため、そうしています。

4

3 に答える 3

18

これはあなたのために働くはずです:

static Action<object, object> BuildSetAccessor(MethodInfo method)
{
    var obj = Expression.Parameter(typeof(object), "o");
    var value = Expression.Parameter(typeof(object));

    Expression<Action<object, object>> expr =
        Expression.Lambda<Action<object, object>>(
            Expression.Call(
                Expression.Convert(obj, method.DeclaringType),
                method,
                Expression.Convert(value, method.GetParameters()[0].ParameterType)),
            obj,
            value);

    return expr.Compile();
}

使用法:

var accessor = BuildSetAccessor(typeof(TestClass).GetProperty("MyProperty").GetSetMethod());
var instance = new TestClass();
accessor(instance, "foo");
Console.WriteLine(instance.MyProperty);

TestClass:

public class TestClass 
{
    public string MyProperty { get; set; }
}

プリントアウト:

ふー

于 2012-05-30T17:01:35.737 に答える
2

動的型を使用します。内部ではリフレクションを使用していますが、はるかに高速です。

さもないと...

寛容なライセンスを持つ無料の高速リフレクション ライブラリがたくさんあります。リンクさせていただきますが、あまりにも多くてどれがあなたに合っているかわかりません. codeplex などで検索してみてください。気に入ったものが見つかったら、試してみてください。

しかし、ええ、おそらくその前に、反射が本当に答えであるかどうかを考えてください. 多くの場合、他の解決策があります。

編集:要求どおり...

http://geekswithblogs.net/SunnyCoder/archive/2009/06/26/c-4.0-dynamics-vs.-reflection.aspx
http://theburningmonk.com/2010/09/performance-test-dynamic-method- invocation-in-csharp-4/
http://www.mssoftwareconsulting.com/msswc/blog/post/C-40-and-dynamic-performance.aspx

私が知る限り常識です。

于 2012-05-30T16:47:52.623 に答える