object.ReferenceEquals 或 == 运算符?
为什么 ThrowIfNull
实现为:
static void ThrowIfNull<T>(this T argument, string name) where T : class
{
if (argument == null)
{
throw new ArgumentNullException(name);
}
}
重写为:
static void ThrowIfNull<T>(this T argument, string name) where T : class
{
if (object.ReferenceEquals(argument, null))
{
throw new ArgumentNullException(name);
}
}
优点:它有助于避免令人困惑的 Equals
重载,并且可能使代码更加清晰。
这样做有什么缺点吗?应该有一些。
Why is ThrowIfNull
implemented as:
static void ThrowIfNull<T>(this T argument, string name) where T : class
{
if (argument == null)
{
throw new ArgumentNullException(name);
}
}
Wouldn't it be better rewritten as:
static void ThrowIfNull<T>(this T argument, string name) where T : class
{
if (object.ReferenceEquals(argument, null))
{
throw new ArgumentNullException(name);
}
}
Pros: it helps avoiding confusing Equals
overloads and probably makes the code more clear.
Any cons to that? There should be some.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
两者没有区别。您将覆盖
Equals
(在任一实现中都没有调用)与重载==
(其中在这两个代码段中都无关紧要,因为重载是在编译时执行的,并且编译器对T
的了解不够,无法使用任何特定的重载)。只是为了说明我的意思:
测试使用:
ThrowIfFoo
不知道T
将是一个字符串 - 因为这取决于调用代码- 并且重载决策仅在编译ThrowIfFoo
时执行。因此,它使用运算符==(object, object)
而不是==(string, string)
。换句话说,它是这样的:
在最后一行,编译器知道它可以使用 == 的重载,因为两个操作数都具有
string
的编译时类型。There's no difference between the two. You're confusing overriding
Equals
(which isn't called in either implementation) with overloading==
(which won't be relevant in either snippet as overloading is performed at compile time, and the compiler doesn't know enough aboutT
to use any specific overload).Just to show what I mean:
Testing with:
ThrowIfFoo
doesn't know thatT
will be a string - because that depends on the calling code - and the overload resolution is only performed whenThrowIfFoo
is compiled. Therefore it's using the operator==(object, object)
rather than==(string, string)
.In other words, it's like this:
In the last line, the compiler knows it can use the overload of == because both operands have compile-time types of
string
.==
运算符在编译时而非运行时解析,并且由于T
是通用的,编译器将使用提供的==
的实现由object
本身检查引用相等性。这正是
object.ReferenceEquals
所做的:调用object
提供的==
实现。The
==
operator is resolved at compile-time, not runtime, and sinceT
is generic the compiler will use the implementation of==
provided byobject
itself, which checks for reference equality.This is exactly what
object.ReferenceEquals
does too: calls the==
implementation provided byobject
.这主要是化妆品。
obj == null
将执行引用检查并返回,如果参数为 null 并且未在T
中覆盖,Equals
也会执行引用检查并返回。当一个参数为空时,它需要一种相当古怪/恶意的实现来返回 true。This is a mostly cosmetics.
obj == null
will do a reference check and return, so willEquals
if the argument is null and it's not overriden inT
. It would require a pretty wonky/malicious implementation to return true when one argument is null.