PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0

Friday, November 4, 2022

[FIXED] How to create an object with dynamic property name and parse with System.Linq.Expressions?

 November 04, 2022     c#, lambda, linq     No comments   

Issue

Based on the requirement I need to pass a dynamically generated property name for the dynamic object below.

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

Instead of State I should be able to pass any name. Here is my code so far. Everything works but I cannot figure it out how to make the property name dynamic. Something like 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;

Solution

Not sure you can do that with anonymous types, but you can do that with ExpandoObject, like this:

    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);
    }


Answered By - Evk
Answer Checked By - Mary Flores (PHPFixing Volunteer)
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Newer Post Older Post Home

0 Comments:

Post a Comment

Note: Only a member of this blog may post a comment.

Total Pageviews

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
Comments
Atom
Comments

Copyright © PHPFixing