带有表达式参数的过程

时间:2013-11-22 15:23:24

标签: c# linq-expressions

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

3 个答案:

答案 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节)存在于参数的类型中   到相应参数的类型

在您的情况下,参数的类型(SomeClassSomeOtherClass)与参数的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)
        {
        }
    }
}