2014-07-08 77 views
1

我想用C#中某種類型的Lambda表達式返回方法(或方法信息)。MemberExpression是否可以返回方法

public class MyClass { 
    public object ReturnSomething(string arg, int numericArg) 
    {/*...*/} 
} 

然後,後來,我想引用使用Lambda像這樣這個方法..

public static void Run<T>(T sourceObject, Expression<Func<T, object>> memberExpression, IEnumerable<object> parameters) 
{ 
    var methodInfo = ((MemberExpression)memberExpression.Body).Member as MethodInfo; 
    if (methodInfo == null) 
     throw new ArgumentException("memberExpression must yield a method"); 
    /*...*/ 
} 

我已經使用這個具有類似的嘗試:

var myClassObject = new MyClass(); 
Run(myClassObject, o => o.ReturnSomething, new object["string arg", 1]); 

但我不斷收到我的表達式編譯器錯誤:

無法將方法組'ReturnSomething'轉換爲非委託類型 'object'。你打算採用這種方法嗎?

這是在c#中可行嗎?或者我應該放棄並傳遞一個字符串的方法名稱並使用反射來查找而不是使用MemberExpression?

+0

不能說我明白了點吧,爲什麼你需要這樣做?動態執行的要點是允許非編碼源驅動執行,這種方法要求您提供方法和參數。我錯過了什麼? –

回答

0

T McKeown問上述正確的問題,當我很容易地在我的lambda表達式中提供參數時,我中途使用了動態執行。

我解決了這個問題,而不是做愚蠢的東西..而不是返回實際的方法,我改變了結構爲我們一個執行內聯執行的表達式。看起來比我最初去的地方清潔得多。

意圖是比較兩個類似分類對象的執行情況,以確保它們都返回相同的值。這是因爲我處於重寫過程中,並希望確保我的新方法返回與舊方法相同的結果。

這裏就是我結束了:

public static void CompareExecutions<TObject, TParameter, TReturn>(this TObject originalSource, TObject alternateSource, IEnumerable<TParameter> parameters, Func<TObject, TParameter, TReturn> testExpression) 
    where TObject : class 
    where TReturn : class 
{ 
    var originalResults = new List<TReturn>(); 
    using (new Profile("Original Source")) 
     foreach (var parameterSet in parameters) 
      originalResults.Add(testExpression(originalSource, parameterSet)); 

    var alternateResults = new List<TReturn>(); 
    using (new Profile("Alternate Source")) 
     foreach (var parameterSet in parameters) 
      alternateResults.Add(testExpression(alternateSource, parameterSet)); 

    var comparer = new PropertyComparer<TReturn>(); 
    int errorCount = 0; 
    for (int i = 0; i < parameters.Count(); i++) 
    { 
     if (!comparer.Equals(originalResults[i], alternateResults[i])) 
     { 
      errorCount++; 
      Debug.WriteLine("^--- Mismatch for parameter {0}:\r\n\t{1}", i, string.Join("\r\n\t", parameters.ElementAt(i))); 
     } 
    } 

    if (errorCount > 0) 
     Assert.Fail("The results did not match for {0} items", errorCount); 
} 

我用這樣的:

public class OriginalClass 
{ 
    public virtual ResultClass MyMethod(string argOne, int argTwo) 
    {/*...*/} 
} 

public class DerivedClass: OriginalClass 
{ 
    public override ResultClass MyMethod(string argOne, int argTwo) 
    {/*New implementation of the original code...*/} 
} 
//[...] 
public void TestTheseTwoClasses() { 
    var original = new OriginalClass(); 
    var derivedClass = new DerivedClass(); 

    original.CompareExecutions(
     derivedClass, 
     new[] { 
      new {One = "First", Two=1}, 
      new {One = "Second", Two=2}, 
      new {One = "Third", Two=3} 
     }, 
     (c,p) => c.MyMethod(p.One, p.Two) 
    ); 
} 
相關問題