2010-07-22 97 views
2

我希望能夠做到這一點:如何將lambda表達式作爲返回方法的參數?

var test = SomeMethod(s => s.SomeMethod); 

我可以通過使方法簽名看起來像這樣使它與屬性的作用:

SomeMethod<TProperty>(Expression<Func<T, TProperty>> expression) 

我怎樣才能使它與方法的工作?我知道這很簡單,我只是想念一些小事。

+0

什麼s.SomeMethod'的'類型簽名? – stakx 2010-07-22 18:33:19

+3

你到底想要做什麼? :)我很想看到答案... – 2010-07-22 18:33:52

+0

他正在嘗試做的事情就像'Func >' – 2010-07-22 18:37:36

回答

1

起訂量,要求該方法的參數接近此用特殊的「標記」來排除對象,如:

test.Setup(m => m.SomeMethod(It.IsAny<int>())); 

順便說一句,這使得起訂量解決方法重載(如果你一個方法名稱不明確唐沒有任何所需參數的概念。)他們正在進一步研究並使用它來根據標準實際匹配參數,目的是模擬單元測試的對象。 source code is available,可能會給你一些想法。他們用表情樹做各種有趣的詭計。


這裏是基於Moq的源上的示例(遭出了一點,但示出了如何方法可以從表達中提取):

internal static void ExtractMethod<T>(Expression<Action<T>> expression) 
     where T : class 
    { 
      var methodCall = expression.ToMethodCall(); 
      var method = methodCall.Method; 
      var args = methodCall.Arguments.ToArray(); 
    } 

直接從Moq的源:

/// <summary> 
    /// Casts the body of the lambda expression to a <see cref="MethodCallExpression"/>. 
    /// </summary> 
    /// <exception cref="ArgumentException">If the body is not a method call.</exception> 
    public static MethodCallExpression ToMethodCall(this LambdaExpression expression) 
    { 
     Guard.NotNull(() => expression, expression); 

     var methodCall = expression.Body as MethodCallExpression; 
     if (methodCall == null) 
     { 
      throw new ArgumentException(string.Format(
       CultureInfo.CurrentCulture, 
       Resources.SetupNotMethod, 
       expression.ToStringFixed())); 
     } 

     return methodCall; 
    } 

這將與您的代碼一起工作,但您必須傳遞「虛擬」參數以允許編譯器創建表達式。所以,如果你有:

public void SomeMethod(int value, string text) {} 

然後,你把它作爲:

ExtractMethod(s => s.SomeMethod(0, null)); 
0

是這樣的?

public SimpleCommand(Predicate<object> canExecuteDelegate, Action<object> executeDelegate) 
    { 
     CanExecuteDelegate = canExecuteDelegate; 
     ExecuteDelegate = executeDelegate; 
    } 

您將需要使用Predicate或Action來指定函數簽名。

+0

絕對不是第一個參數,因爲Predicate返回true或false ...我不認爲第二個工程,除非我做錯了... 在我的SomeMethod方法中,我需要能夠訪問有關方法本身被傳入 – 2010-07-22 18:35:24

+0

然後我錯過了那個部分所以你需要一個表達式來獲取函數的名字(或者其他的東西)? – 2010-07-22 18:39:22

+0

是的,基本上我需要名字...和關於參數的信息它需要,如果可能的話(雖然沒有必要,但atm) – 2010-07-22 18:40:32

0
class Program 
    { 
     public class Test 
     { 
      public bool SomeMethod(string test) 
      { 
       return true; 
      } 
     } 

     static void Main(string[] args) 
     { 

      Test testObj = new Test(); 


      Func<string, bool> rule1 = AddRule(testObj, x => x.SomeMethod); 

      bool rsult = rule1("ttt"); 

     } 

     static Func<string, bool> AddRule<T>(T obj, Func<T,Func<string, bool>> func) 
     { 
      return func(obj); 
     } 


} 
+0

這樣做的方式需要我知道方法簽名,正確嗎?這不是一種可能性 – 2010-07-22 18:46:28

+0

是的,沒有辦法知道方法簽名,因爲他們可能是無限的可能性 – 2010-07-22 18:47:49

+0

@Max,棘手的問題;) – 2010-07-22 18:48:13

1

是這樣的東西你在找什麼?

DoSomethingWithAction<T>(Func<T, Action> actionRetriever) { } 
DoSomethingWithFunction<T, TResult>(Func<T, Func<TResult>> functionRetriever) { } 

你會叫這些名字:

DoSomethingWithAction<ObjectWithMethod>(obj => obj.Method); 
DoSomethingWithFunction<ObjectWithProperty>(obj => obj.Property); 
0

我想,有沒有這樣做,而不指定方法簽名的方法:試想重載方法:

void SomeMethod() { } 
int SomeMethod(int a, int b) { return 0; } 

// ... 

var test = TestMethod(s => s.SomeMethod); 

會如何編譯器可能知道,你想測試哪種方法?

相關問題