2013-11-22 2 views
1

SafeRun은 다음 호출 시나리오를 올바르게 처리해야합니까?수식의 인수가있는 프로 시저

SafeRun(new SomeClass(arg1, arg2)); 
SafeRun(new SomeOtherClass()); 
SafeRun(someObject.FooReturningVoid()); 

내가 해봤 다음하지만 성공 :(없이

protected void SafeAct<TResult>(Expression<Func<TResult>> expression) 
protected void SafeAct(Expression<Action> expression) 

SafeRun 실제로이 수행합니다

protected void SafeAct<TResult>(Expression<Func<TResult>> expression) 
{ 
    try 
    { 
     Expression.Lambda<Func<TResult>>(expression).Compile()(); 
    } 
    catch (Exception e) 
    { 
     ThrownException = e; 
    } 
} 

내가 람다와 SafeAct를 호출 대안을 허용하지 않습니다 표현식! :

I DON'T WANT THIS: 
SafeRun(() => new SomeClass()); 
+0

'SafeRun (someObject.FooReturningVoid()); – rhughes

+0

그 이름으로 언급 한 것은 FooReturningVoid가 다음과 같이 선언 된 함수라는 것입니다 :'void FooReturningVoid()' – SOReader

+1

생각했습니다. 왜 다른 방법으로 그것을 전달하겠습니까?그것은 void를 반환합니다. 그래서 lazyberezovsky가 아래에서 언급했듯이 할 수 없습니다. – rhughes

답변

3

이 두 호출은 단지 표현

SafeRun(new SomeClass(arg1, arg2)); 
SafeRun(new SomeOtherClass()); 

에 주조 할 수 없으며 공백을 통과하는 것은 모든

SafeRun(someObject.FooReturningVoid()); 

에서 C#으로 허용되지 않는 개체 인스턴스를 반환하기 때문에 당신은이 작업을 수행 할 수 없습니다 applicable function member 검증을 살펴보면 다음과 같이 나타납니다.

함수 멤버는 해당 함수라고합니다. m 다음의 조건이 모두 참인 경우 인수 목록 A에 대해 을 사용합니다.

A의 인수 개수는 함수 멤버 선언 의 매개 변수 개수와 동일합니다. A의 각 인자를 들어

인수의 파라미터 통과 모드 (즉, 아웃 값 (REF) 또는 인) 대응 파라미터의 매개 변수 전달 모드와 동일 이며, 값 파라미터 또는 대 파라미터 배열 암시 적 변환 (섹션 6.1) 암시 적 변환 인자 ( SomeClass, SomeOtherClass의 형태에서 존재하지 케이스의 해당 파라미터

의 형식으로 인수 유형에서 존재)를 매개 변수의 Expression<Action> 유형으로 변경하십시오. 메소드에 전달할 표현식 유형과 유형 간의 암시 적 변환을 정의 할 경우에만 코드가 작동합니다.

+0

하지만 "SafeRun"함수의 본문에서 실행되는 표현식으로 "매개 변수"를 해석하고 싶습니다. – SOReader

+1

@SOReader 처음 두 경우에는 표현식을 전달하지 않습니다. 두 생성자는 모두 메서드 호출 전에 실행됩니다. 단순히 객체 인스턴스를 전달하는 것입니다. –

1

첫 번째 호출의 경우 (Java의 스레드와 비슷 함) 메서드를 표시하는 ISafeRunable 인터페이스를 만듭니다. 프로토 타입은 다음과 같아야합니다 : void SafeRun(IRunable).

두 번째 호출에서는 대리자를 만들거나 작업 대리자를 사용합니다. 프로토 타입은 다음과 같아야합니다 : void SafeRun(Action actionDelegate). 그리고 이것을 이렇게 부르세요 SafeRun(someObject.VoidFunction);

0

대표자를 사용해 보셨습니까?

using System; 
using System.Collections.Generic; 
using System.IO; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 

namespace throw_test 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      Program p = new Program(); 

      p.Run(); 
     } 

     public delegate void SafeRunDelegate(object sender, EventArgs e); 

     public void Run() 
     { 
      this.SafeRun(this.MyMethodToSafelyRun); 
     } 

     public void SafeRun(SafeRunDelegate d) 
     { 
      if (d != null) 
       d(this, new EventArgs()); 
     } 

     public void MyMethodToSafelyRun(object sender, EventArgs e) 
     { 
     } 
    } 
} 
+0

사실, 이것은 단지 람다 접근법을 능가합니다 : /하지만 어쨌든 고마워요. – SOReader