2013-11-22 3 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());' - return void ?? – rhughes

+0

То, что я называю с этим именем, это то, что FooReturningVoid - это функция, объявленная так: 'void FooReturningVoid()' – SOReader

+1

Я думал это. Почему вы передадите это другому методу?Он возвращает пустоту, так как лазиберовский упоминает ниже, что нельзя сделать. – rhughes

ответ

3

Вы не можете этого сделать, потому что эти два вызова просто возвращает экземпляр объекта, который не может быть преобразован в выражение

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

И проходя пустоту не допускается в C# на всех

SafeRun(someObject.FooReturningVoid()); 

Посмотрите на проверку applicable function member, вы увидите, что

Функциональный элемент называется применимой функцией m ember с в отношении списка аргументов A, когда все из них верны:

Число аргументов в A идентично количеству параметров в объявлении члена функции.

Для каждого аргумента в A, прохождение режима аргумента параметр (то есть, значение, ссылка, или из) является идентичен параметр ближнего режима соответствующего параметра и для параметра значения или массив параметров, неявного преобразования (раздел 6.1) существует с типа аргумента к типу соответствующего параметра

в вашем случае нет неявного преобразования существует от типа аргумента (SomeClass, SomeOtherClass) к параметру Expression<Action>. Ваш код будет работать только в том случае, если вы определите неявные преобразования между типами выражений и типами, которые вы передаете методу.

+0

Но я хочу, чтобы «параметр» интерпретировался как выражение, которое я выполняю в теле функции «SafeRun» ... – SOReader

+1

@SOReader вы не передаете выражение в первых двух случаях. Оба конструктора выполняются перед вызовом метода. Вы просто передаете экземпляры объектов –

1

Для первого вызова сделайте интерфейс ISafeRunable, который предоставляет метод void Run() (вроде Threads в Java). Прототип должен выглядеть так: void SafeRun(IRunable).

Для второго вызова сделайте делегата или просто используйте делегат Action. Прототип должен выглядеть так: 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

Смежные вопросы