覆盖等于并与字符串进行比较

Sco*_*ock 4 c# equals

我已经定义了一个带有字符串成员的C#类.对于所有意图而言,将此类视为字符串的子类(除非不允许).我用它来表示一个匹配特定格式的强类型字符串字段(我已经大大简化了这一点).

public class field
{
    private readonly string m_field;
    public field(string init_value)
    {
        //Check the syntax for errors
        if (CheckSyntax(init_value))
        {
            m_field = init_value;
        }
        else
        {
            throw new ArgumentOutOfRangeException();
        }
    }

    public override string ToString()
    {
        return m_field;
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,我希望能够将此类直接与任何其他字符串(对象或文字)进行比较.因此,我在课堂上实现了以下内容:

public override bool Equals(object obj)
{
    if (obj == null)
    {
        return false;
    }

    return this.m_field == obj.ToString();
}

public override int GetHashCode()
{
    return this.m_field.GetHashCode();
}

public static bool operator ==(field x, Object y)
{
    if ((object)x == null && y == null)
    {
        return true;
    }
    else if ((object)x == null || y == null)
    {
        return false;
    }
    else
    {
        return (x.m_field == y.ToString());
    }
}

public static bool operator !=(field x, Object y)
{
    return !(x == y);
}
Run Code Online (Sandbox Code Playgroud)

现在,当我正在编写单元测试时,根据我在Assert.AreEqual的参数中传递的顺序,我会得到不同的结果:

string valid = "Some String";
field target = new field(valid);
Assert.AreEqual(target, valid); // PASSES
Assert.AreEqual(valid, target); // FAILS
Run Code Online (Sandbox Code Playgroud)

我假设这是因为在第一个断言中,它调用field.Equals(),在第二个断言中调用String.Equals().显然我是从错误的角度接近这个.谁能给我一些见解?

另一件事.我不能在这里使用结构(值类型),因为在我的实际情况中,我在基类中定义所有这些并继承它.

Jon*_*eet 9

基本上你不能做你想做的事 - 你无法string为平等目的认出你的班级.你将永远无法使它反身 - 你将永远无法使它服从合同object.Equals.

我个人会尝试重新设计它,以便您没有将验证作为类型本身的一部分 - 使其成为业务实体的相关属性(或者它们是什么)的一部分.


Eug*_*ota 5

这在Effective Java中作为第8项详细描述:在覆盖时遵守常规协定equals.

equals方法实现了等价关系.

它是Reflexive,Symmetric,Transitive,Consistent,对于任何非null引用x,x.equals(null)必须返回false.打破对称性的例子与你的相似.

fieldclass知道string类,但内置string类不知道field.这是一种单向互操作性,应该被删除.