简体   繁体   English

object.ReferenceEquals或==运算符?

[英]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.

相关问题 Object.ReferenceEquals永远不会命中 - Object.ReferenceEquals never hit C#operator ==,StringBuilder.Equals,Object.Equals和Object.ReferenceEquals之间的差异 - C# Differences between operator ==, StringBuilder.Equals, Object.Equals and Object.ReferenceEquals Object.ReferenceEquals对于匹配的字符串返回true - Object.ReferenceEquals returns true for matching strings IEnumerable、Where 和 Object.ReferenceEquals 的问题 - Issue with IEnumerable, Where, and Object.ReferenceEquals Object.ReferenceEquals为两个不同的对象输出true - Object.ReferenceEquals prints true for two different objects &#39;Object.ReferenceEquals&#39;始终为false,因为它使用值类型进行调用 - 'Object.ReferenceEquals' is always false because it is called with a value type Assert.ReferenceEquals()在Visual Studio Test中Object.ReferenceEquals()返回&#39;false&#39;的位置 - Assert.ReferenceEquals() Passes where Object.ReferenceEquals() returns 'false' in Visual Studio Test c#中Object.Equals(object,object)和Object.ReferenceEquals(object,object)之间的区别 - difference between Object.Equals(object,object) and Object.ReferenceEquals(object,object) in c# 为什么我要在Equals覆盖中执行object.ReferenceEquals(null,this)? - Why would I ever want to do object.ReferenceEquals(null, this) in Equals override? 参考平等性能差异? ((object)obj1 ==(object)obj2)vs。object.ReferenceEquals(obj1,obj2) - Reference equality performance difference? ((object)obj1 == (object)obj2) vs. object.ReferenceEquals( obj1, obj2 )
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM