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;
}
}
我不接受使用lambda表达式调用SafeAct的替代方法!:
I DON'T WANT THIS:
SafeRun(() => new SomeClass());
答案 0 :(得分:3)
你不能这样做,因为这两个调用只返回对象实例,不能将其转换为表达式
SafeRun(new SomeClass(arg1, arg2));
SafeRun(new SomeOtherClass());
在C#中不允许传递void
SafeRun(someObject.FooReturningVoid());
查看applicable function member验证,您会看到
一个函数成员被认为是一个适用的函数成员 当满足以下所有条件时,尊重参数列表A:
A中的参数数量与参数数量相同 函数成员声明。
对于A中的每个参数,参数 参数的传递模式(即value,ref或out)是 与相应的参数传递模式相同 参数,以及值参数或参数数组, 隐式转换(第6.1节)存在于参数的类型中 到相应参数的类型
在您的情况下,参数的类型(SomeClass
,SomeOtherClass
)与参数的Expression<Action>
类型之间不存在隐式转换。只有在定义表达式类型和传递给方法的类型之间进行隐式转换时,您的代码才有效。
答案 1 :(得分:1)
对于第一次调用,创建一个公开方法ISafeRunable
的接口void Run()
(有点像Java中的Threads)。原型应该如下void SafeRun(IRunable)
。
对于第二个调用,请创建一个委托或仅使用Action委托。原型应该如下void SafeRun(Action actionDelegate)
。并称之为SafeRun(someObject.VoidFunction);
答案 2 :(得分: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)
{
}
}
}