通用参数未被强制执行

时间:2017-01-31 23:41:58

标签: c# .net generics nunit nunit-3.0

我有以下自定义NUnit约束。它(当正确实施时)测试是给定的DateTime等于明天。

public class TomorrowConstraint : Constraint
{
    public TomorrowConstraint()
    {
        Description = "Tomorrow";
    }

    public override ConstraintResult ApplyTo<DateTime>(DateTime actual)
    {
        return new ConstraintResult(this, actual, true);
    }
}

请注意,我已将Type参数赋予具体类型,而不是泛型类型。

以下测试使用它:

[TestFixture]
public class X
{
    [Test]
    public void Foo()
    {
        Assert.That("string", new TomorrowConstraint());
    }
}

我传递的是string而不是一个DateTime,但是字符串会毫无问题地传递给方法。

如果我查看带有actual.GetType()的类型,我可以看到它是一个字符串:{Name = "String" FullName = "System.String"}

这是怎么回事?

我以为我会在某个地方得到一个例外?

1 个答案:

答案 0 :(得分:0)

好吧,正如我推测和李证实的那样,行

public override ConstraintResult ApplyTo<DateTime>(DateTime actual)

不会将通用类型约束为DateTime。相反,它只使用DateTime作为泛型参数的标识符,例如T在其他情况下。要实际约束泛型类型,您需要使用where关键字:

public override ConstraintResult ApplyTo<T>(T actual) where T : DateTime

...除了那些也不会工作,因为泛型类型约束必须是接口或非密封类,并且DateTime是密封的。因此,我不确定是否有办法仅使用泛型来获得编译时类型的安全性。您可以做的是使用另一种方法调用该方法的DateTime版本并将其用于单元测试:

public ConstraintResult ApplyTo(DateTime actual)
{
    return ApplyTo<DateTime>(actual);
}