2014-04-19 24 views
5

我需要創建一個調用動態對象的System.Linq.Expressions.Expression。動態對象可以是ExpandoObject或任何其他IDynamicMetaObjectProvider構建.NET表達式以調用動態對象的正確方法

考慮以下測試:

var myInstance = DateTime.Now; 

var methodInfo = myInstance.GetType().GetMethod("ToUniversalTime"); 

var methodCallExpression = Expression.Call(Expression.Constant(myInstance), methodInfo); 
var expression = Expression.Lambda(methodCallExpression); 

Assert.AreEqual(myInstance.ToUniversalTime(), expression.Compile().DynamicInvoke()); 

我需要創建一個等效表達式時將myInstance被聲明等(只是作爲例子):

dynamic myInstance = new ExpandoObject(); 
myInstance.MyMethod = new Func<string>(() => "hello world"); 

我假設我需要使用Expression.Dynamic方法(見MSDN)。但我不知道如何使用它。我試圖在谷歌搜索,但我發現使用Microsoft.CSharp.RuntimeBinder.Binder班上唯一的例子(見MSDN)不能正式使用:

此API支持.NET Framework基礎結構,不適合使用直接從您的代碼。

使用Microsoft.CSharp.RuntimeBinder.Binder我可以寫代碼如下:

dynamic myInstance = new ExpandoObject(); 
myInstance.MyMethod = new Func<string>(() => "hello world"); 

var binder = Binder.InvokeMember(
    CSharpBinderFlags.None, 
    "MyMethod", 
    null, 
    this.GetType(), 
    new[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.Constant, null) }); 

var methodCallExpression = Expression.Dynamic(binder, typeof(object), Expression.Constant(myInstance)); 
var expression = Expression.Lambda(methodCallExpression); 

Assert.AreEqual(myInstance.MyMethod(), expression.Compile().DynamicInvoke()); 

它這個解決方案是否正確?

+1

是的,這是我如何在CSharpEval中實現它 – EnderWiggin

回答

-1
dynamic x = typeof("<<MethodName>>") 
      .GetMethod("ToUniversalTime") 
      .Invoke(<<Type Of Object>>, new object[] { [Parameter1,]      
      [Parameter2,....] }); 
在此代碼「類型」,而不是從哪個類型的對象,你必須調用方法

...

指定,而不是「方法名」

,最後你的對象你的方法名稱,而不是

,如果沒有參數,再通過空數組...其他明智的傳球,而不是「parameter1,2,等「對象類型」。

+1

我正在尋找一種方法來構建表達式樹,請參閱表達式類。你的代碼通過反射簡單地調用一個方法。 –

1

這裏是貓ch:從我的理解來看,沒有某種Binder對象進行動態調用沒有意義。

粘結劑對象表示遵循動態域名解析的規則:

  • 應該匹配區分大小寫?
  • 應如何解決方法重載?
  • 如果對象是非動態對象該怎麼辦?
  • 你使用的是什麼回退?

換句話說,所述Binder對象表示主叫「語言」的語義,而IDynamicMetaObjectProvider代表被調用對象的語義。

所以,是的,我們不應該使用CSharp Binder對象。這可以被感覺到,特別是當一些問題發生時,只能通過使用對象的內部工作來解決。然而,替代方案僅僅是使用另一個非框架提供的實現。

相關問題