字符串等式运算符==在c#中

时间:2012-02-16 19:24:38

标签: c# string operator-overloading equality

我试图在C#中查看为字符串类中的比较运算符实现的代码。发现的是:

//THIS IS NOT WHAT I MEANT
public static bool Equals(object objA, object objB)
{
    return ((objA == objB) || (((objA != null) && (objB != null)) && objA.Equals(objB)));
}

//THIS IS WHAT I SEE REALLY and the above is what I would expect to see
public static bool Equals(string a, string b)
{
    return ((a == b) || (((a != null) && (b != null)) && EqualsHelper(a, b)));
}



public static bool operator ==(string a, string b)
{
    return Equals(a, b);
}

我不知道反射器是否在玩我的技巧,但是当我尝试为我自己的类实现这个策略时,我得到了Equals和重载的==运算符之间的无限循环(如预期的那样) 。在字符串类中是否有不同或者是我的Reflector报告

static Equals(object o1, object o2)
Object类上的

方法是String类的一部分吗?

4 个答案:

答案 0 :(得分:7)

没有String.Equals(object, object)方法 你看到Object.Equals

它没有递归的原因是objA == objB调用内置对象相等运算符,而不是自定义字符串相等运算符。
(根据操作数的编译时类型解析运算符重载)

答案 1 :(得分:6)

C#中的等式运算符不是多态的。在评估objA == objB时,您实际上正在执行==(object a, object b)运算符实现(检查引用相等性),而不是==(string a, string b),因为objA和{的声明类型{1}}变量为objB,而不是object

您在代码中可能犯的错误是,在评估string运算符之前,您没有将类实例强制转换为object

假设你有:

==

...您需要将其替换为:

public static bool Equals(MyClass objA, MyClass objB)
{
    return objA == objB || objA != null && objB != null && objA.Equals(objB);
}

......相当于:

public static bool Equals(MyClass objA, MyClass objB)
{
    return (object)objA == (object)objB || objA != null && objB != null && objA.Equals(objB);
}

更新public static bool Equals(MyClass objA, MyClass objB) { return object.ReferenceEquals(objA, objB) || objA != null && objB != null && objA.Equals(objB); } 类包含两者一个String方法一个static bool Equals(string a, string b)方法。不同之处在于前者是在static bool Equals(object a, object b)类本身中定义的,而后者是从String类(它是Object的基类)继承的。您的反射器可能会也可能不会根据其设置显示继承的方法。

在您发布的代码中,由于声明的StringobjA类型为objB,因此无论实例如何,都会调用具有object参数的运算符'实际类型。

更新 2 :您更新的代码确实包含无限递归。我认为它可能是反射器工具中的一个错误。

更新 3 :这似乎是反汇编中的错误。实现object运算符的第一个条件在反汇编的C#代码中显示为Equals(string a, string b)。但是,IL代码的前几行实际上是:

a == b

bne.un.s被定义为“如果两个无符号整数值不相等(无符号值),则为指定偏移处的目标指令的分支,短格式。”

因此,似乎正在执行引用相等。

答案 2 :(得分:1)

一个不太混乱的解决方案:不要使用==运算符:

public static bool Equals(MyClass a, MyClass b) 
{ 
    return ReferenceEquals(a, b)
        || ((!ReferenceEquals(a, null) && !ReferenceEquals(b, null)) && a.Equals(b))); 
} 

答案 3 :(得分:0)

它引用的equals方法是:

public static bool Equals(string a, string b)
{
    /* == is the object equals- not the string equals */
    return a == b || (a != null && b != null && string.EqualsHelper(a, b));
}

public static bool operator ==(string a, string b)
{
    return string.Equals(a, b);
}

即。一个等于两个字符串而不是两个对象的方法。