2014-04-03 76 views
-3

我有一個對象類型的參數。任何東西都可以在該參數上設置。我需要在該參數中找到具有特定名稱的屬性。如果它當然存在。使用正確類型調用委託

我需要的是這樣的(僞代碼):

ParameterExpression arg = Expression.Parameter(parameter.GetType(), "x"); 
Expression expr = Expression.Property(arg, "Info"); 

var propertyResolver = Expression.Lambda<Func<parameter.GetType, object>>(expr, arg).Compile(); 

已經有方法`Expression.Lambda(類型,表達,...)

但返回System.Delegate回對我而言,我需要Func <>。

我該怎麼做才能做到這一點?

在此先感謝你們。

這裏是一個演示:

class Program 
{ 
    private Func<object, object> func; 

    static void Main(string[] args) 
    { 
     // lets say in this case the parameter is person but it could be anything 
     Person parameter = new Person(); 

     ParameterExpression arg = Expression.Parameter(parameter.GetType(), "x"); 
     Expression expr = Expression.Property(arg, "Name"); 
     var func = Expression.Lambda<Func<parameter.GetType, object>>(expr, arg).Compile(); 
    } 
} 

class Person 
{ 
    public string Name { get; set; } 
} 

我創造了我的功能我必須把它至少1000倍在對內部的另一種方法循環後因此DynamicInvoke是不是一個不錯的選擇。它太慢了。我嘗試了一下。

+1

* *你的表現限制是什麼?你的方法是否可以變成通用的,這樣''parameter'的類型可以作爲類型參數來使用?何時以及如何打電話給代表? (大概不只是''參數'...) –

+0

該方法本身必須實現,因爲它從一個接口,所以我不能改變任何東西,但我可以調用其他方法。這裏的表現非常重要。因此我需要在本地存儲創建的功能。 –

+2

請提供所有這些信息 - 以及您可以在問題*中告訴我們的任何其他信息。我們不應該一次就把它從你身上拖出來。 –

回答

2

兩個問題需要考慮:

  • 使用動態類型調用一個通用的方法,該方法將返回一個Func<object, object>您可以通過在以後使用包裝一個表達式樹編譯的代表:

    public Func<Object, Object> CreateFunc(object sampleValue) 
    { 
        dynamic dynamicValue = sampleValue; 
        return CreateFuncImpl(dynamicValue); // Dynamic type inference 
    } 
    
    private Func<Object, Object> CreateFuncImpl<T>(T sampleValue) 
    { 
        // You could use Delegate.CreateDelegate as another option - 
        // you don't need expression trees here 
        var parameter = Expression.Parameter(parameter.GetType(), "x"); 
        var expression = Expression.Property(arg, "Name"); 
        var func = Expression.Lambda<Func<T, object>>(expression, parameter) 
             .Compile(); 
        return (object actualValue) => func((T) actualValue); 
    } 
    
  • 裹在表達式樹轉換表達式屬性表達式:

    public Func<Object, Object> CreateFunc(object sampleValue) 
    { 
        var parameter = Expression.Parameter(typeof(object), "x"); 
        var conversion = Expression.Convert(parameter, sampleValue.GetType()); 
        var property = Expression.Property(conversion, "Name"); 
        return Expression.Lambda<Func<object, object>>(property, parameter) 
            .Compile(); 
    } 
    

這兩個與值假設你做的創作很少,然後調用委託多次相同的類型。它們可能會或可能不會成爲你需要的東西 - 很難用較弱的要求來說明。當然,它們確實要求您稍後調用函數的值是正確的類型。

+0

好的謝謝。我會在一分鐘內測試它們。請問你認爲哪兩種選擇哪種更快? –

+0

@devhedgehog:不知道 - 我還沒有編譯它們。他們可能大致相同。你會發現當你嘗試雖然:) –

+0

好的測試結果在這裏。耶穌我覺得我應該吻你的腳或什麼。第二個與轉換是最快的。實際上它與'Func func = x => x.Name'具有相同的時間。好了,現在我相信你是c#的教父。我爲所有的麻煩applogize。我不明白爲什麼你們需要更多的信息,因爲我只是問如何用funcs做到這一點。我只想用funcs來測試它。它不在我的手中,以暴露這個項目的很多。其相當複雜的wpf內容在那裏和性能很差。謝謝你幫助我很多。 –

1

也許這將適合您的需要:

Expression.Lambda(Type, Expression, IEnumerable<ParameterExpression>) 
      .Compile() 
      .DynamicInvoke(...)