不强制执行通用参数
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);
}
我有以下自定义 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);
}