Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/306.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
当存在指定类型的运算符重载时,C#编译器如何确定泛型方法中的引用相等性?_C#_Generics_Operator Overloading_Equality - Fatal编程技术网

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

当存在指定类型的运算符重载时,C#编译器如何确定泛型方法中的引用相等性?,c#,generics,operator-overloading,equality,C#,Generics,Operator Overloading,Equality,目前正在阅读Jon Skeet的“C#Depth,3rd edition”,我有一个关于引用平等的小问题。对于那些感兴趣的人来说,下面的代码是来自CHPTR3的Jon代码的一个小变体。p、 80: 存储在类中的公共函数;请注意,“T”被约束为引用类型: public static bool AreReferencesEqual<T>(T i1, T i2) where T : class { return i1 == i2; } 与Jon的解

目前正在阅读Jon Skeet的“C#Depth,3rd edition”,我有一个关于引用平等的小问题。对于那些感兴趣的人来说,下面的代码是来自CHPTR3的Jon代码的一个小变体。p、 80:

存储在类中的公共函数;请注意,“T”被约束为引用类型:

    public static bool AreReferencesEqual<T>(T i1, T i2) where T : class
    {
        return i1 == i2;
    }
与Jon的解释一致,当我运行驱动程序文件时,它的输出是“True”、“False”。现在,我认为我完全理解了这一点,但当我将驱动程序文件更改为以下内容时,我感到惊讶:

    static void Main(string[] args)
    {
        string one = "one";
        string two = "one";
        Console.WriteLine(one == two);
        Console.WriteLine(ReferenceEquality.AreReferencesEqual(one, two));
    }
并在输出上看到“真”、“真”。这背后的原因是什么?泛型方法现在是使用字符串运算符==重载,还是由于我不知道的一些微妙的编译器技术,引用确实相等?还是我完全错过了机会,误解了乔恩的解释


感谢您花时间阅读和响应。

它们是等效的引用,因为编译器使用相同的底层字符串,因为常量匹配。字符串(幕后)在C#中是不可变的-当您将字符串添加到一起时,将生成一个新的字符串实例-这在您的第二个代码集中从未发生过,因此它们实际上都引用RAM中的相同字节块。

请将他称为Lord Skeet,他将向您致意directly@CarbineCoder哈,谢谢。我想当我继续深入他的书时,我会接受这个建议。干杯。平等在C#中令人困惑。你可能对此感兴趣,你也可以自己验证一下。将字符串2的赋值更改为类似字符串2=“on”+“e”;隐马尔可夫模型。。。那么编译器可以通过优化技术判断底层字符数组是否相等?为什么第一个代码集不能从中受益?尽管存在连接,“one”的底层数组等于“two”(正如我们从测试1中的字符串运算符==的输出中看到的,代码集1)。如果编译器基于字符串的常量值执行这些技术,它难道不能看到我使用了相同的调用(即使是串联调用),因此只能像在集合一中一样使用相同的引用吗?如果没有,为什么不呢?不管怎样,你的问题肯定回答了“是什么”,所以我接受了!不过,如果你能就我上述关于“如何”的问题提供多一点信息,我将不胜感激是基于引用的对象的运行时操作(可以重载,等等),因此编译器不会在那里进行任何优化-尽管从技术上讲字符串是一个烘焙类,但在编译器理解“+”的含义方面,它不会得到任何特殊处理(在这种情况下,这是两个常数的直接串联,这意味着是的,可以使用共享常数)。@otto null澄清了很多问题。再次感谢。
    static void Main(string[] args)
    {
        string one = "one";
        string two = "one";
        Console.WriteLine(one == two);
        Console.WriteLine(ReferenceEquality.AreReferencesEqual(one, two));
    }