簡體   English   中英

具有動態參數的表達式樹

[英]Expression Trees with dynamic parameter

我想將其轉換為:

Func<dynamic, object> myFunc = t => return t.Name + " " + t.Surname;

進入表達式樹。

我想出的是:

ParameterExpression target = ExpressionParameter(typeof(dynamic), "target");
ParameterExpression result = ExpressionParameter(typeof(object), "result");
BlockExpression block = Expression.Block(
     new [] { result },
     Expression.Assign(
           result,
           Expression.Add(
                 Expression.Add(
                      Expression.Property(target, "Name"),
                      Expression.Constant(" ", typeof(string))
                 ),
                 Expression.Property(target, "Surname")
           )
     )
);
Func<dynamic, object> myFunc = Expression.Lambda<dynamic, object>>(block, target).Compile();

但是,編譯器不喜歡typeof(dynamic) ,我有點typeof(dynamic) dynamic不是一種類型,它本質上是一個object

因此,我着手更改ParameterExpression

ParameterExpression target = ExpressionParameter(typeof(object), "target");

現在可以編譯代碼,但是在運行時出現問題。

我正在嘗試獲取target的屬性Name的值,如果對象是dynamic ,則可能有意義。

但是由於target被認為是object類型,因此Expression拋出一個錯誤,告訴我Name不作為屬性存在。

是否有用於獲取動態屬性的表達式?

對於那些對解決方案感興趣的人:

ParameterExpression target = Expression.Parameter(typeof(object), "target");
ParameterExpression result = Expression.Parameter(typeof(object), "result");

CallSiteBinder getName = Binder.GetMember(
   CSharpBinderFlags.None, "Name", typeof(Program),
   new CSharpArgumentInfo[] {
       CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null)
   }
);

CallSiteBinder getSurname= Binder.GetMember(
   CSharpBinderFlags.None, "Surname", typeof(Program),
   new CSharpArgumentInfo[] {
       CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null)
   }
);

BlockExpression block = Expression.Block(
    new[] { result },
    Expression.Assign(
        result,
        Expression.Call(typeof(string).GetMethod("Concat", new Type[] { typeof(object[]) }),
                        Expression.NewArrayInit(typeof(object),
                             Expression.Dynamic(getName, typeof(object), target),
                             Expression.Constant(" ", typeof(object)),
                             Expression.Dynamic(getSurname, typeof(object), target)
                        )
       )
    )
);

Func<dynamic, object> myFunc = Expression.Lambda<Func<dynamic, object>>(block, target).Compile();

這正是我在做什么:

  1. 創建一個CallSiteBinder ,獲取動態屬性的值作為參數傳遞的動態對象的Name
  2. 創建了一個CallSiteBinder ,它獲取作為參數傳遞的動態對象的動態屬性Surname的值
  3. 調用方法string.Concat(params object[] args) 為此,我需要將參數作為object數組發送。 我正在使用getName" "getSurname的值創建數組。

我使用以下答案作為指導和參考:

C#4在表達式樹中“動態”

使用以上方法,可以執行以下操作:

dynamic person = new ExpandoObject();
person.Name = "Matt";
person.Surname = "Smith";

object value = myFunc(person);
Console.WriteLine(value); //Will print out "Matt Smith"

//Internally it just calls:
//string.Concat(new object[] { person.Name, " ", person.Surname });

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM