在泛型方法操作符重载操作、方法

由网友(明知是戏)分享简介:这code段是从C#中的深度This code snippet is from C# in Depthstatic bool AreReferencesEqual(T first, T second)where T : class{return first == second;}static void Main...

这code段是从C#中的深度

This code snippet is from C# in Depth

    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));
    }

以上code段的输出是

The output of the above code snippet is

True 
False

在main方法改为

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

以上code段的输出是

The output of the above code snippet is

True 
True

我无法捉摸为什么呢?

I cannot fathom why ?

编辑:一旦你理解了串实习下面的问题不适用。

Once you understand string-interning following questions don't apply.

如何在第二code段的通用方法 AreReferencesEqual 收到的参数?

How are the parameters received at the Generic method AreReferencesEqual in the second code snippet ?

什么改变为字符串类型,当它连接起来,使==操作符不会调用字符串类型的重载equals方法?

What changes to the string type when it is concatenated to make the == operator not call the overloaded Equals method of the String type ?

推荐答案

在字符串的情况下,你可能不打算使用引用相等。 要访问通用的方法,平等和不平等,最好的办法是:

On the case of strings, you probably don't intend to use reference equality. To access equality and inequality in generic methods, your best bet it:

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);
}

这仍然使用重载的等于,但处理空值等了。对于不平等,这种处理空值,两个 IComparable的&LT; T&GT; IComparable的

This still uses the overloaded Equals, but handles nulls etc too. For inequality, this handles nulls, and both IComparable<T> and IComparable.

有关其他运营商,请参见 MiscUtil 。

For other operators, see MiscUtil.

回复的问题;在的情况下:

Re the question; in the case of:

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

您获得因为编译器和运行时的设计是高效的处理字符串;所使用的任何文字被拘留和相同的情况下,使用的每一次你的AppDomain。在编译(而不是运行时)也做了CONCAT如果可能的话 - 也就是

You get true, true because the compiler and runtime is designed to be efficient with strings; any literals that you use are "interned" and the same instance is used every time in your AppDomain. The compiler (rather than runtime) also does the concat if possible - i.e.

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

是如出一辙code 作为previous例子。没有区别的。但是,如果你强迫它在运行时连接字符串,它假定他们很可能是短暂的,所以他们的没有的实习/再利用。因此,在这样的:

is exactly the same code as the previous example. There is no difference at all. However, if you force it to concatenate strings at runtime, it assumes they are likely to be short-lived, so they are not interned/re-used. So in the case:

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

你有4串; 乔恩(实习),我的名字是(实习),和两个不同的实例我的名字是乔恩。因此, == 返回true,引用相等返回false。但价值相等( EqualityComparer&LT; T&GT; .DEFAULT )。仍然会返回true

you have 4 strings; "Jon" (interned), "My name is " (interned), and two different instances of "My name is Jon". Hence == returns true and reference equality returns false. But value-equality (EqualityComparer<T>.Default) would still return true.

阅读全文

相关推荐

最新文章