2016-04-22 10 views
1

ich die Lösung der Frage bin mit: Reflection Performance - Create Delegate (Properties C#)Reflection Leistung - Erstellen Delegate (Eigenschaften C#) mit abhängigen Parameter

Wo ich den folgenden Code haben:

private static Action<object, object> BuildSetAccessor(string name, MethodInfo method) 
{ 
    if (method == null) return null; 
    if (method.DeclaringType == null) return null; 
    var obj = Expression.Parameter(typeof(object), name); 
    var value = Expression.Parameter(typeof(object)); 
    var 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(); 
} 

private static Func<object, object> BuildGetAccessor(string name, MethodInfo method) 
{ 
    if (method.DeclaringType == null) return null; 
    var obj = Expression.Parameter(typeof(object), name); 
    var expr = Expression.Lambda<Func<object, object>>(Expression.Convert(Expression.Call(Expression.Convert(obj, method.DeclaringType), method), typeof(object)), obj); 
    return expr.Compile(); 
} 

-Code im Einsatz ...

var cacheProperty = new CacheForReflectionClassProperty() 
       { 
        Name = p.Name, 
        SetValue = BuildSetAccessor(p.Name, p.GetSetMethod()), 
        GetValue = BuildGetAccessor(p.Name, p.GetGetMethod()) 
       }; 
if (Attribute.IsDefined(p, typeof(IsIdentityColumn))) 
{ 
    // TODO: Instead of just getting the old value, 
    // I need to verify if the value is NULL 
    // in that case I need to create a new value of ID type.... 
    // and at the end I need to use the SetValue() method as well 
    GetValue = .... // TODO: 
} 
else if (Attribute.IsDefined(p, typeof(IsCreatedOnColumn))) 
       { 
    // TODO: Instead of just getting the old value, 
    // I need to verify if the value is NULL 
    // in that case I need to create a new value with DateTime.UtcNow 
    // and at the end I need to use the SetValue() method as well 
    GetValue = .... // TODO: 
       } 

ich weiß, dass ich die folgenden Methoden erstellen müssen:

private static Func<object, object> BuildGetAccessorForIdentityColumn(string name, MethodInfo method) 

private static Func<object, object> BuildGetAccessorForCreatedOnColumn(string name, MethodInfo method) 

Ich habe versucht zu lernen, wie man Ausdrucksbäume verwendet, aber ich habe keinen Weg gefunden, wo mein BuildGetAccessor nicht nur den Wert erhält, sondern auch das Ergebnis mit etwas vergleicht und bei Bedarf auch den BuildSetAccessor verwenden muss.

Wie kann ich das tun?

Antwort

2

Sie tun dies, weil Reflexion Einfluss auf die Leistung hat. Aber nachdem Sie mit Reflexion Teil fertig sind - Sie brauchen nicht mehr kompilierte Ausdrücke verwenden - nur regelmäßige Code verwenden:

var getAccessor = BuildGetAccessor(p.Name, p.GetGetMethod()); 
    var setAccessor = BuildSetAccessor(p.Name, p.GetSetMethod()); 
    // if IsCreatedOnColumn 
    cacheProperty.GetValue = (instance) => 
    { 
     var value = getAccessor(instance); 
     if (value == null) 
     { 
      value = DateTime.UtcNow; 
      setAccessor(instance, value); 
     } 
     return value; 
    }; 
+0

Heute habe ich Zeit hatte, um diese zurück zu bekommen und mit Ihrem Code konnte ich tun was ich wollte. Danke :) (Ich gebe Ihnen eine Stimme und die richtige Antwort). – Dryadwoods