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

Bob*_*r02 3 c# string equality operator-overloading

我试图在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);
}
Run Code Online (Sandbox Code Playgroud)

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

static Equals(object o1, object o2)
Run Code Online (Sandbox Code Playgroud)

Object类上的方法是String类的一部分吗?

SLa*_*aks 7

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

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


Dou*_*las 6

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

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

假设你有:

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

...你需要用以下代替它:

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

......相当于:

public static bool Equals(MyClass objA, MyClass objB)
{
    return object.ReferenceEquals(objA, objB) || objA != null && objB != null && objA.Equals(objB);
}
Run Code Online (Sandbox Code Playgroud)

更新:本String类包含两个一个static bool Equals(string a, string b)方法一个static bool Equals(object a, object b)方法.不同之处在于前者是在String类本身内定义的,而后者是从Object类(它是基类String)继承的.您的反射器可能会也可能不会根据其设置显示继承的方法.

在您发布的代码,因为声明的类型的objAobjBobject,然后与运营商object的参数会被调用,不管各实例的实际类型.

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

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

ldarg.0
ldarg.1
bne.un.s IL_0006

ldc.i4.1
ret
Run Code Online (Sandbox Code Playgroud)

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

因此,似乎正在执行参考相等.