C#委托为对象

时间:2013-05-21 09:35:11

标签: c# .net delegates nunit method-group

免责声明:此问题的单元测试相关信息并不十分相关 - 如果您对此不熟悉,可以跳至 “问题” ,但它有助于设定背景。

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

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

我想使用NUnit parametrized unit-test来测试所有这些方法。这是测试方法:

    [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.CheckByteRange的方法,该方法需要string并返回void

我尝试了什么(并且失败成功了):

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

1 个答案:

答案 0 :(得分:4)

如果方法是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 },
          };