2010-07-22 7 views
2

나는이 작업을 수행 할 수 있도록하려면 :메서드를 반환하는 매개 변수로 람다 식을 사용하려면 어떻게해야합니까?

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

나는 메소드 서명은 다음과 같이하여이 속성 작업을 할 수 있습니다 :

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

나는 그것이 방법과 작동 방법을 만들 수 있습니까? 나는 이것이 단순하다는 것을 알고, 나는 단지 작은 것을 놓치고있다.

+0

s.SomeMethod''의 유형 서명은 무엇입니까 :

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

은 그럼 당신은로 전달거야? – stakx

+3

대체 무슨 짓을하려는거야? :) 대답을보고 궁금합니다 ... –

+0

그가하려고하는 일은'Func > ' –

답변

1

MOQ 같은 오브젝트 특별한 '마커'함께 스텁되는 메소드 매개 변수를 요구함으로써이 접근 필요한 매개 변수에 대한 개념이 없습니다.) 단위 테스트를 위해 객체 조롱을 위해 기준을 기반으로 매개 변수를 실제로 일치시키기 위해 조금 더 나아가고 있습니다. 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; 
    } 

이것은 코드에서 작동하지만 컴파일러가 표현식을 만들 수 있도록 '더미'매개 변수를 전달해야합니다. 그래서 만약 당신이 있었다 :

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

이와 비슷한 기능이 있습니까?

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

술어 또는 동작을 사용하여 함수 서명을 지정해야합니다.

+0

Predicate가 true 또는 false를 반환하기 때문에 첫 번째 매개 변수가 아닙니다. 두 번째 매개 변수가 잘못되어 있지 않으면 작동하지 않을 것이라고 생각합니다. SomeMethod 메서드에서 정보에 액세스 할 수 있어야합니다. 전달 된 메서드 자체 –

+0

그 부분을 놓친 다음 함수의 이름을 얻기 위해 표현식이 필요합니까? –

+0

그래, 기본적으로 이름과 매개 변수에 대한 정보가 필요합니다. 가능하다면 (atm은 필요하지 않습니다.) –

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

이 방법을 사용하면 메소드 서명을 알아야합니다. 정확하지 않습니다. –

+0

예, 메소드 서명을 알지 못하면 방법이 없습니다. 무한한 가능성. –

+0

@Max, 까다로운 질문;) –

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); 

어떻게 것 컴파일러는 아마도 당신이 테스트하고자하는 메소드를 알고있을 것입니다. 덧붙여

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

는,이 메소드 오버로드를 (당신이 경우 하나의 메소드 이름은 돈 모호 해결하기 위해 MOQ 수 있습니다 :

관련 문제