代码之家  ›  专栏  ›  技术社区  ›  abhilash

泛型方法中的运算符重载

  •  6
  • abhilash  · 技术社区  · 16 年前

    此代码段来自C#深度

        static bool AreReferencesEqual<T>(T first, T second)
            where T : class
        {
            return first == second;
        }
    
        static void Main()
        {
            string name = "Jon";
            string intro1 = "My name is " + name;
            string intro2 = "My name is " + name;
            Console.WriteLine(intro1 == intro2);
            Console.WriteLine(AreReferencesEqual(intro1, intro2));
        }
    

    上述代码段的输出是

    True 
    False
    

    当主方法更改为

        static void Main()
        {
            string intro1 = "My name is Jon";
            string intro2 = "My name is Jon";
            Console.WriteLine(intro1 == intro2);
            Console.WriteLine(AreReferencesEqual(intro1, intro2));
        }
    

    上述代码段的输出是

    True 
    True
    

    我不明白为什么?

    泛型方法如何接收参数 AreReferencesEqual 在第二段代码中?

    3 回复  |  直到 15 年前
        1
  •  13
  •   Marc Gravell    16 年前

    对于字符串,您可能不打算使用引用相等。

    EqualityComparer<T>.Default.Equals(x,y); // for equality
    Comparer<T>.Default.Compare(x,y); // for inequality
    

    static bool AreValuesEqual<T>(T first, T second)
        where T : class
    {
        return EqualityComparer<T>.Default.Equals(first,second);
    }
    

    这仍然使用重载的 Equals ,但也处理空值等。对于不等式,它处理空值,并且两者都处理 IComparable<T> IComparable .

    MiscUtil .


        string intro1 = "My name is Jon";
        string intro2 = "My name is Jon";
        Console.WriteLine(intro1 == intro2);
        Console.WriteLine(AreReferencesEqual(intro1, intro2));
    

    true 符合事实的 因为编译器和运行时被设计为对字符串有效;您使用的任何文本都是“interned”,并且每次在AppDomain中都使用相同的实例。这个 编译程序 (而不是运行时)如果可能,也会执行concat-即。

        string intro1 = "My name is " + "Jon";
        string intro2 = "My name is " + "Jon";
        Console.WriteLine(intro1 == intro2);
        Console.WriteLine(AreReferencesEqual(intro1, intro2));
    

    完全相同的代码 实习/重复使用。因此,在这种情况下:

        string name = "Jon";
        string intro1 = "My name is " + name;
        string intro2 = "My name is " + name;
        Console.WriteLine(intro1 == intro2);
        Console.WriteLine(AreReferencesEqual(intro1, intro2));
    

    两个不同的例子 “我的名字叫乔恩”。因此 == EqualityComparer<T>.Default )仍将返回真值。

        2
  •  5
  •   shahkalpesh    16 年前

    我猜乔恩在其中一个问题中说,我试图回答。

    在泛型版本中,它调用object.ReferenceEquals(这不同于==。对于字符串,==进行值比较)。

    结果,连接的版本返回false,而常量(文字字符串)版本返回true。

    编辑:我认为乔恩一定在附近,用一种更好的方式来解释这一点:)
    懒惰的我,我已经买了这本书,但还没有开始(

        3
  •  2
  •   Rune FS    16 年前

    在main的第一个版本中,您有:

    string name = "Jon";
    string intro1 = "My name is " + name;
    string intro2 = "My name is " + name;
    

    这将创建4个字符串。其中两个是编译时常量,即“Jon”和“My name is”,但在初始化intro1和intro2时,编译器不能说名称始终是Jon,并解析值runtime,为intro1和intro2中的每一个创建一个新字符串。

    string intro1 = "My name is Jon";
    string intro2 = "My name is Jon";
    

    您只有一个字符串,这是一个编译时常量:“我的名字是Jon”,您将该字符串分配给intro1和intro2,这就是原因

    AreReferencesEqual(intro1, intro2)