c#委托作为对象

本文关键字:对象 | 更新日期: 2023-09-27 18:14:49

免责声明:这个问题的单元测试相关信息不是真正相关的-如果你不熟悉这个,你可以跳到" the Problem",但它有助于设置上下文。

我有一个需要进行单元测试的类。它看起来像这样:

public class NumberParser {
    public static void CheckByteRange(string str){...}
    [...]
    public static void CheckFloatRange(string str){...}
    [...]
}

我想使用一个NUnit参数化单元测试来测试所有这些方法。下面是测试方法:

    [TestCaseSource("CheckRange_Overflow_Inputs")]
    public void CheckRange_Overflow(string value, Action<string> method)
    {
        Assert.Throws<Exception>(() => method(value));
    }

测试使用TestCaseSourceAttribute指定一个字段,该字段包含测试方法的参数集列表。

现在,NUnit期望一个名为CheckRange_Overflow_Inputs的字段,类型为object[],它本身包含object[]个元素,每个元素包含测试方法的参数值。

问题:

理想情况下,我想这样写字段:

    private static readonly object[] CheckRange_Overflow_Inputs
        = new object[]
              {
                  new object[]{byte.MaxValue,  NumberParser.CheckByteRange },
                  [...]
                  new object[]{float.MaxValue, NumberParser.CheckFloatRange },
                  [...]
              };

但是编译器抱怨它不能将方法组强制转换为对象。

这是有意义的- NumberParser.CheckByteRange可能是不明确的,例如,它可能是重载的。

但是我怎么能让编译器允许我保存(作为一个对象)方法称为NumberParser.CheckByteRangestring和返回void ?

What I tried (and

failed succeeded):
 [...]
 new object[]{byte.MaxValue, (Action<string>)NumberParser.CheckByteRange },
 [...]

c#委托作为对象

如果方法是static,那么您的尝试将会成功。它不能简单地作为

(Action<string>)NumberParser.CheckByteRange

CheckByteRange是一个实例(非static)方法,因为你没有告诉它使用哪个实例(this)。所以:

  • 使CheckByteRange成为static方法
  • 告诉它使用哪个实例,即(Action<string>)someInstance.CheckByteRange

使用它们static,以下编译对我来说很好:

private static readonly object[] CheckRange_Overflow_Inputs
    = new object[]
          {
              new object[]{byte.MaxValue,  (Action<string>) NumberParser.CheckByteRange },
              new object[]{float.MaxValue, (Action<string>) NumberParser.CheckFloatRange },
          };