【问题标题】:Convert method to Delegate?将方法转换为委托?
【发布时间】:2010-12-20 15:04:27
【问题描述】:

我想打电话给例如TryDo.Do(MessageBox.Show(""), null);

我该怎么做??

using System;

namespace TryCatchHandlers
{
    public static class TryDo
    {
        public static CallResult Do(Delegate action, params object[] args)
        {
            try
            {
                return new CallResult (action.DynamicInvoke(args), action.Method.ReturnType, true);
            }
            catch
            {
                return new CallResult(null, null, false);
            }
        }
    }

    public class CallResult
    {
        public CallResult() { }

        internal CallResult(object result, Type resultType, bool isSuccessful)
        {
            Result = result;
            ResultType = resultType;
            IsSuccessful = isSuccessful;
        }
        public object Result { get; private set; }
        public Type ResultType { get; private set; }
        public bool IsSuccessful { get; private set; }
    }
}

【问题讨论】:

  • DynamicInvoke 很慢。
  • @slaks:我可以用什么代替?

标签: .net delegates c#-4.0


【解决方案1】:

您的代码调用MessageBox.Show,然后尝试将结果传递给TryDo。
由于MessageBox.Show 不返回Delegate,所以这行不通。

相反,您应该传递Show 方法本身以及一个参数:

TryDo.Do(new Func<string, DialogResult>(MessageBox.Show), "");

或者,您可以传递调用该​​函数的匿名方法:

TryDo.Do(new Action(() => MessageBox.Show("")));

请注意,如果您使用 Funcs 和 Actions 而不是采用 Delegate 并调用 DynamicInvoke 的泛型重载,您的函数将执行得更快。

【讨论】:

  • @slaks: 我喜欢TryDo.Do(new Action(() =&gt; MessageBox.Show(""))); 方法,我应该如何更改TryDo.Do() 以获得一个函数并运行它?
  • 我想打电话给TryDo.Do(Foo, args[]);
  • @HPT:如果你进行了接受特定委托的重载,C# 将隐式推断委托类型。
  • @slaks: 所以你的意思是我写了Do(Action), Do(Action&lt;in T1&gt;), Do(Action&lt;inT1, in T2&gt;), .... and , Do(Func&lt;out Tresult&gt;), Do(Func&lt;in T1, out Tresult&gt;), Do(Func&lt;in T1, in T2, out Tresult&gt;), ...? ?
  • @HPT:是的,除了没有in 和out,并且在方法中有泛型参数。
【解决方案2】:

试试这个:

Delegate d = (Action)delegate { MessageBox.Show(""); };
TryDo.Do(d, null);

【讨论】:

    【解决方案3】:

    因为MessageBox.Show("")是方法调用,不是委托,所以

    TryDo.Do(MessageBox.Show(""),null);
    

    实际上尝试使用MessageBox.Show 调用的结果调用TryDo.Do。

    您实际上需要传输一个包含您尝试调用的方法的委托,因为

    TryDo.Do(MessageBox.Show,null);
    

    也将失败,并出现无法将方法强制转换为委托的错误。
    从方法创建委托的最简单方法是使用Func&lt;..&gt; 和Action&lt;...&gt; 泛型委托(Func 用于返回某些内容的方法,Action 用于那些无效的方法),如下所示:

    var myDelegate = new Func<string, DialogResult>(MessageBox.Show);
    TryDo.Do(myDelegate, null)
    

    【讨论】:

    • 正是我的意思,您传递的是方法调用的结果,而不是方法本身(MessageBox.Show 返回 DialogResult)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-01-30
    • 1970-01-01
    • 1970-01-01
    • 2010-09-08
    • 1970-01-01
    • 2015-12-24
    • 1970-01-01
    相关资源
    最近更新 更多