[英]object.ReferenceEquals or == operator?
Why is ThrowIfNull
implemented as: 为什么
ThrowIfNull
实现为:
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. 优点:它有助于避免混淆
Equals
重载,并可能使代码更清晰。
Any cons to that? 对此有何不妥? There should be some.
应该有一些。
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 about T
to use any specific overload). 您在使用重载
==
会混淆覆盖 Equals
(在任一实现中都没有调用)(由于在编译时执行了重载,并且编译器对T
的使用不够了,因此在任何一个片段中都不相关任何特定的超载)。
Just to show what I mean: 只是为了表明我的意思:
static void ThrowIfFoo<T>(this T argument, string name) where T : class
{
if (argument == "foo")
{
throw new Exception("You passed in foo!");
}
}
Testing with: 测试:
"foo".ThrowIfFoo(); // Throws
string x = "f";
x += "oo"; // Ensure it's actually a different reference
x.ThrowIfFoo(); // Doesn't throw
ThrowIfFoo
doesn't know that T
will be a string - because that depends on the calling code - and the overload resolution is only performed when ThrowIfFoo
is compiled . ThrowIfFoo
不知道T
将是一个字符串 - 因为这取决于调用代码 - 并且只有在编译ThrowIfFoo
时才执行重载ThrowIfFoo
。 Therefore it's using the operator ==(object, object)
rather than ==(string, string)
. 因此它使用operator
==(object, object)
而不是==(string, string)
。
In other words, it's like this: 换句话说,它是这样的:
object foo1 = "foo";
string tmp = "f";
object foo2 = tmp + "oo";
Console.WriteLine(foo1.Equals(foo2)); // Prints True
Console.WriteLine(foo1 == foo2); // Prints false
Console.WriteLine((string) foo1 == (string) foo2); // Prints True
In the last line, the compiler knows it can use the overload of == because both operands have compile-time types of string
. 在最后一行中,编译器知道它可以使用==的重载,因为两个操作数都具有编译时类型的
string
。
The ==
operator is resolved at compile-time, not runtime, and since T
is generic the compiler will use the implementation of ==
provided by object
itself, which checks for reference equality. ==
运算符在编译时解析,而不是运行时,并且由于T
是通用的,编译器将使用object
本身提供的==
的实现,它检查引用相等性。
This is exactly what object.ReferenceEquals
does too: calls the ==
implementation provided by object
. 这正是
object.ReferenceEquals
所做的:调用object
提供的==
实现。
This is a mostly cosmetics. 这主要是化妆品。
obj == null
will do a reference check and return, so will Equals
if the argument is null and it's not overriden in T
. obj == null
将执行引用检查并返回,因此如果参数为null并且它不在T
重写,则将为Equals
。 It would require a pretty wonky/malicious implementation to return true when one argument is null. 当一个参数为null时,它需要一个非常不稳定/恶意的实现来返回true。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.