简体   繁体   English

当指定类型的运算符重载存在时,C#编译器如何确定泛型方法中的引用相等性?

[英]How does C# compiler determine reference equality in generic methods when operator overloads for a specified type exists?

Currently going through Jon Skeet's "C# In Depth, 3rd edition" and I have a small question concerning reference equality. 目前正在研究乔恩·斯基特(Jon Skeet)的“ C#In Depth,第3版”,我对引用相等有一个小问题。 For those interested, the following code is a small variation of Jon's code from Chptr 3. p.80: 对于感兴趣的人,以下代码是Chptr 3 p.80的Jon代码的很小变化:

Public Function stored in a class; 公共功能存储在一个类中; note that 'T' is constrained to reference types: 请注意,“ T”仅限于引用类型:

    public static bool AreReferencesEqual<T>(T i1, T i2) where T : class
    {
        return i1 == i2;
    }

Driver method: 驱动方式:

    static void Main(string[] args)
    {
        string name = "Joe";
        string one = "one" + name;
        string two = "one" + name;
        // test one (uses string operator== overload, and returns true)
        Console.WriteLine(one == two);

        // test two (according to Jon, when the compiler compiles the generic method,
        // it has no idea what overloads will be provided, and therefore treats
        // the == comparison with respect to the more general 'object' type.
        // Therefore this method should return false because, of course, the value
        // of the references 'one' and 'two' are not the same.
        Console.WriteLine(ReferenceEquality.AreReferencesEqual(one, two));
    }

In consistency with Jon's explanation, the output of the driver file when I run it is "True", "False". 与Jon的解释一致,运行该驱动程序文件时,输出为“ True”,“ False”。 Now, I thought I understood this completely, but I was surprised when I changed the driver file to this: 现在,我以为我完全理解了这一点,但是当我将驱动程序文件更改为此时,我感到很惊讶:

    static void Main(string[] args)
    {
        string one = "one";
        string two = "one";
        Console.WriteLine(one == two);
        Console.WriteLine(ReferenceEquality.AreReferencesEqual(one, two));
    }

and saw "True", "True" on the output. 并在输出上看到“ True”,“ True”。 What is the reasoning behind this? 这背后的原因是什么? Is the generic method now using the string operator== overload, or are the references indeed equal as a result of some subtle compiler technique I am unaware of? 现在是使用字符串operator ==重载的通用方法,还是由于我不知道的某些微妙的编译器技术,引用确实相等吗? Or have I completely missed the boat and misinterpreted Jon's explanation? 还是我完全错过了船,误解了乔恩的解释?

Thanks for taking the time to read and respond. 感谢您抽出宝贵的时间阅读和回复。

They are reference-equivalent because the compiler is using the same underlying string because the constants match. 它们是引用等效的,因为常量匹配,因此编译器使用相同的基础字符串。 Strings (behind the scenes) are immutable in C# - when you add strings together, a new string instance is generated - that never happens in your second code set, so they are, in fact, both referencing the same chunk of bytes in RAM. 字符串(在幕后)在C#中是不可变的-当您将字符串添加在一起时,会生成一个新的字符串实例-在第二个代码集中永远不会发生,因此,它们实际上都引用RAM中相同的字节块。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 c#泛型函数类型不适应重载 - c# generic function type not adapting to overloads C#泛型类型相等运算符 - C# generic types equality operator C#:为什么动态有助于确定在泛型方法中使用的类型参数? - C#: Why does dynamic help determine type argument for use in generic methods? C#,XmlDoc:如何引用方法重载 - C#, XmlDoc: How to reference method overloads 我们如何检查实现相等运算符的类型的引用相等性? - How can we check reference equality for a type that implements equality operator? 当泛型类型为absract,TSymmetricAlgorithm时如何在C#中使用泛型类型方法 - How to use generic type methods in C# when the generic type is absract, TSymmetricAlgorithm 当使用具有new()约束的泛型类型调用new时,为什么c#编译器会发出Activator.CreateInstance? - Why does the c# compiler emit Activator.CreateInstance when calling new in with a generic type with a new() constraint? C#中的反射和运算符重载 - Reflection and Operator Overloads in C# `typeof`运算符如何在泛型方法中获取类型参数? - How does `typeof` operator get type argument in generic methods? 使用运算符重载时,C#编译器如何确定哪种实现适用于混合类型操作数? - With operator overloading, how does the C# compiler decide which implementation applies with mixed-type operands?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM