2012-07-16 77 views
1

我已經結束了在那裏的函數表達式樹Expression<Func<TClass, TProperty>>在後面的代碼分配給類型對象的全局變量,然後一個情況下,我需要調用不同的方法與表達方式。我無法更改全局對象類型;它必須是對象。CAST函數表達式樹從對象

當試圖用全局對象調用第二個方法時,代碼將不會編譯,除非我將該對象作爲Expression<Func<TClass, TProperty>>進行投射。問題是我不知道什麼TProperty是第二個方法被調用的點。

我創建了一個快速演示應用程序來說明(VS2010中編寫的c#控制檯應用程序) - 真正的應用程序看起來不像這樣。

using System; 
using System.Linq.Expressions; 

namespace FuncExpressionTree 
{ 
    public class ViewModel 
    { 
     public string StringProperty { get; set; } 
     public int IntProperty { get; set; } 
    } 

    public class Helper<T> 
     where T : ViewModel 
    { 
     private object _global; 

     public void Execute() 
     { 
      AssignToGlobal((T vm) => vm.StringProperty); 

      ProcessGlobal(); 

      AssignToGlobal((T vm) => vm.IntProperty); 

      ProcessGlobal(); 
     } 

     public void AssignToGlobal<TClass, TProperty>(Expression<Func<TClass, TProperty>> expression) 
     { 
      _global = expression; 
     } 

     public void ProcessGlobal() 
     { 
      // invalid cast exception thrown when IntProperty is assigned to _global 
      AssignToGlobal((Expression<Func<T, string>>)_global); 
     } 
    } 

    class Program 
    { 
     static void Main(string[] args) 
     { 
      (new Helper<ViewModel>()).Execute(); 
     } 
    } 
} 

如果我們專注於Execute()方法。

  1. 第一個全局被指定爲字符串屬性的表達式。
  2. ProcessGlobal執行並工作,因爲我正在鑄造到Expression<Func<T, string>>
  3. Next 全局被賦值爲int屬性的表達式。
  4. ProcessGlobal再次執行,但此時它會拋出無效的轉換異常。它會工作,如果我改變它,而不是鑄造Expression<Func<T, int>>,但然後字符串屬性不起作用。 Expression<Func<T, object>>也會拋出無效的強制轉換異常。

我覺得我在想念的東西,它應該可以做一些與System.Linq.Expressions命名空間來動態調用第二個方法(如內ProcessGlobal AssignToGlobal在上面的例子)。

那麼我怎麼能得到這個以通用的方式工作?

回答

1
public void ProcessGlobal() 
    { 
     var globalType = _global.GetType(); // globalType = Expression<Func<TClass, TProperty>> 
     var functionType = globalType.GetGenericArguments()[0]; // functionType = Func<TClass, TProperty> 
     var functionGenericArguments = functionType.GetGenericArguments(); // v = [TClass, TProperty] 
     var method = this.GetType().GetMethod("AssignToGlobal").MakeGenericMethod(functionGenericArguments); //functionGenericArguments = AssignToGlobal<TClass, TProperty> 
     method.Invoke(this, new[] { this._global }); // Call AssignToGlobal<TClass, TProperty>)(this._global); 
    } 
+0

感謝這對我工作,雖然我需要調整它與2參數,即TClass實例和全局調用。 – 2012-07-17 06:22:09

+0

如果您發現任何問題,請通知我「非工作代碼」,我會幫助您... – user1494736 2012-07-17 22:14:25