不强制执行通用参数

Generic arguments not being enforced

我有以下自定义 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"}.

这是怎么回事?

我以为我会在某个地方遇到异常?

好吧,正如我推测和李证实的那样,这条线

public override ConstraintResult ApplyTo<DateTime>(DateTime actual)

不限制泛型为DateTime。相反,它只是使用 DateTime 作为泛型参数的标识符,就像其他情况下的 T 一样。要真正约束泛型,需要使用where关键字:

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

... 除了那也行不通,因为泛型类型约束必须是接口或 non-sealed class,并且 DateTime 是密封的。所以我不确定是否有办法单独使用泛型来获得 compile-time 类型安全。您可以做的是使用另一种方法调用该方法的 DateTime 版本并将其用于您的单元测试:

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