【问题标题】:Method with Var Method input?带有 Var Method 输入的方法?
【发布时间】:2011-11-13 20:47:40
【问题描述】:

在 C# 中:

是否可以定义一个输入参数是任何方法的方法?

让我更好地描述一下:

我想要一个带有签名的方法

bool IsDoit(var method)
{
    try
    {
        method(...);
        return true;
    }
    catch{return false;}
}

这会获取一个方法并返回一个布尔值,是否抛出异常!

通用代表?通用动作?通用函数?

您有什么想法或不可能

【问题讨论】:

  • 最好不要返回 bool,而是返回 Exception 对象

标签: c#


【解决方案1】:

这里的“...”会是什么?听起来您想要某个描述的委托 - 并且委托签名应该与您要调用的方法之一匹配。例如:

static bool IsDoit(Action method)
{
    try
    {
        method();
        return true;
    }
    catch
    {
        return false;
    }
}

这将允许任何无参数 void 方法的方法组转换:

if (IsDoIt(SomeMethodWithNoParameters))
{
}

如果调用者想要调用带有其他参数的方法,他们可以使用 lambda 表达式将其包装在 Action 中:

if (IsDoIt(() => MethodWithParameters("first", "second"))
{
}

就我个人而言,首先我不确定这种设计的智慧,请注意 - 在没有任何日志记录的情况下捕获异常并吞下它们对我来说似乎是一个非常糟糕的主意.

【讨论】:

  • 我同意你关于捕捉异常并吞下它们的观点。谢谢你的想法。
  • @RedHat:除了Exception已经是引用类型,所以不能写Nullable<Exception>。但我仍然通常不鼓励这样做;处理异常的惯用方式是将它们抛出而不是返回。可能有一些种情况是合适的,但我认为它们非常罕见。
【解决方案2】:

是的,对于无参数方法,将 var 替换为 Action

【讨论】:

    【解决方案3】:

    您可以将您的方法作为委托传递,例如使用操作:

    bool IsDoit(Action test)
    {
       test(...);
    } 
    

    【讨论】:

      【解决方案4】:

      您始终可以接受通用委托。代表都来自System.Delegate

      using System;
      
      public class Program
      {
          public delegate R Deleg1<R,T1>(T1 arg);
          public delegate R Deleg2<R,T1,T2>(T1 arg1, T2 arg2);
          public delegate R Deleg3<R,T1,T2,T3>(T1 arg1, T2 arg2, T3 arg3);
      
          public static void AcceptAny<R,T1>(Deleg1<R,T1> del) {  /**/ }
          public static void AcceptAny<R,T1,T2>(Deleg2<R,T1,T2> del) {  /**/ }
          public static void AcceptAny<R,T1,T2,T3>(Deleg3<R,T1,T2,T3> del) {  /**/ }
      
          public static void Main(string[] args)
          {
          }
      }
      

      如果你不介意一点点擦除,你可以

      public delegate R DelegParams<R>(params object[] @params);
      public static void AcceptAny<R>(DelegParams<R> paramsFunc) {  /**/ }
      

      您可以间接将大多数委托分配给此签名,方法是使用 lambda 表达式包装它(很像 Jon Skeet 展示的 Action 方法)。

      请注意,委托共享一个公共基类,并允许您使用“类似反射”的接口调用它们(例如,将通用 object[] 作为参数):Delegate.DynamicInvoke Method

      【讨论】:

        猜你喜欢
        • 2018-12-07
        • 2014-05-30
        • 2013-04-03
        • 1970-01-01
        • 2013-03-13
        • 1970-01-01
        • 1970-01-01
        • 2014-06-11
        • 1970-01-01
        相关资源
        最近更新 更多