2016-05-08 4 views
1

Basierend auf der Anforderung muss ich einen dynamisch generierten Eigenschaftsnamen für das dynamische Objekt übergeben.Wie erstellt man ein Objekt mit dynamischem Eigenschaftsnamen und analysiert es mit System.Linq.Expressions?

var dynamicObj = new { State = "Caifornia" }; 

Anstelle von State sollte ich in der Lage sein, einen beliebigen Namen zu übergeben. Hier ist mein Code soweit. Alles funktioniert, aber ich kann nicht herausfinden, wie man den Namen der Eigenschaft dynamisch macht. So etwas wie var dynamicObj = new { "State" = "Caifornia" };

var rule = new Rule("State", "NotEqual", "Florida"); 
var dynamicObj = new { State = "Caifornia" }; 
var expression = Expression.Parameter(dynamicObj.GetType(), "State"); 
var property = Expression.Property(expression, "State"); 
var propertyType = dynamicObj.GetType().GetProperty(rule.MemberName).PropertyType; 

var isValid = false; 
ExpressionType tBinary; 

if (Enum.TryParse(rule.Operator, out tBinary)) 
{ 
     var right = Expression.Constant(Convert.ChangeType(rule.TargetValue, propertyType)); 
     var result = Expression.MakeBinary(tBinary, property, right); 
     var func = typeof(Func<,>).MakeGenericType(dynamicObj.GetType(), typeof(bool)); 
     var expr = Expression.Lambda(func, result, expression).Compile(); 
     isValid = (bool)expr.DynamicInvoke(dynamicObj); 
} 

return isValid; 
+1

ich stark vermuten, dass Sie nicht in der Lage sein, dies zu tun, weil anonyme Typen, die Compiler erfordern um einen geeigneten Typ mit einer Eigenschaft zum Zeitpunkt der Kompilierung zu erstellen. –

+0

Danke @JonSkeet – German

Antwort

1

Nicht sicher, dass mit anonymen Typen tun können, aber Sie können mit ExpandoObject tun, wie folgt aus:

var rule = new Rule("State", "NotEqual", "Florida");    
    var dynamicObj = (IDictionary<string, object>) new ExpandoObject();    
    dynamicObj.Add("State", "California"); 
    var expression = Expression.Parameter(typeof(object), "arg"); 
    // create a binder like this 
    var binder = Microsoft.CSharp.RuntimeBinder.Binder.GetMember(CSharpBinderFlags.None, "State", null, new CSharpArgumentInfo[] { 
      CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) 
     }); 
    // define dynamic property accessor 
    var property = Expression.Dynamic(binder, typeof(object), expression);   
    // the rest as usual 
    var isValid = false; 
    ExpressionType tBinary; 

    if (Enum.TryParse(rule.Operator, out tBinary)) 
    { 
     var right = Expression.Constant(rule.TargetValue); 
     var result = Expression.MakeBinary(tBinary, property, right); 
     var func = typeof(Func<,>).MakeGenericType(dynamicObj.GetType(), typeof(bool)); 
     var expr = Expression.Lambda(func, result, expression).Compile(); 
     isValid = (bool)expr.DynamicInvoke(dynamicObj); 
    } 
+0

Es funktioniert. Danke @Evk – German

0

können Sie Anonimous Typ Verwendung Linq aus früheren definiert properites in somoe Art zu schaffen, aber man kann nicht dynamische Eigenschaft erstellen. Verwenden Sie enum (Kalifornien, Florida und etc.) und der Name dieser Eigenschaft wird angeben.

Verwandte Themen