我一直在阅读C# in Depth, Third Edition,它正在谈论以前我不知道的一些奇怪的泛型行为:==
和!=
泛型中的比较。让我们看看下面的示例:(注意:您可以直接在LinqPad上运行以下代码)
static bool AreEqual<T>(T first, T second)
{
return first == second;
}
您可以按原样使用此方法。当您执行以下代码时,编译器会抱怨并说“运算符'=='不能应用于'T'和'T'类型的操作数”
void Main()
{
int first = 1;
int second = 1;
(first == second).Dump("Normal Comparison");
AreEqual(first, second).Dump("Generic Comparison");
}
如果没有应用类型约束,则只允许您与null
进行比较,如下所示:
static bool AreEqual<T>(T value)
{
return value == null;
}
但是,当您应用如下所示的参考类型约束时,Main()
方法将起作用:
static bool AreEqual<T>(T first, T second) where T:class
{
return first == second;
}
但如果它是Value Type Constraint,则以下代码将不起作用:
void Main()
{
int first = 1;
int second = 1;
(first == second).Dump("Normal Comparison");
AreEqual(first, second).Dump("Generic Comparison");
}
static bool AreEqual<T>(T first, T second) where T:struct
{
return first == second;
}
我认为Jon Skeet正试图在接下来的页面中解释它。他说:
基本上,编译
AreReferencesEqual<T>
时,编译器 不知道会有多少重载 - 就好像是 传入的参数类型为object
。
上面的引用可能就是答案,但我仍然感到困惑,为什么它表现得像这样。顺便说一下,AreReferencesEqual<T>
方法与我的方法与签名static bool AreEqual<T>(T first, T second) where T:class
是一回事。我的问题是为什么我们看到这种奇怪的行为。