IEquatable<string> 不适用于静态 Equals 方法

问题描述 投票:0回答:1

我实现了一个名为 NonEmptyString 的类,它在非空时不允许创建。我让这个类实现了

IEquatable<NonEmptyString>
IEquatable<string>
。我实现了
IEquatable<string>
。我有
Equals(object obj)
Equals(NonEmptyString other)
Equals(string other)
GetHashCode()
的覆盖。然后我写了一些测试,发现几乎一切正常。除了 1 种情况,当调用静态 Equals 方法且字符串参数为第一个参数时。请参阅此处此行。

string text = "ASDF123";
NonEmptyString nonEmptyString = NonEmptyString.CreateUnsafe("ASDF123");
Assert.True(text == nonEmptyString);
Assert.True(nonEmptyString == text);
Assert.True(text.Equals(nonEmptyString));
Assert.True(nonEmptyString.Equals(text));
Assert.True(Equals(text, nonEmptyString)); //This is the only one that doesn't work.
Assert.True(Equals(nonEmptyString, text));

我想知道为什么会出现这种情况 - 当我查看对象上 Equals 方法的实现时,它确实调用了虚拟

Equals(object obj)
方法。因此,如果该方法返回 false,那么我预计同样的情况也应该发生在
text.Equals(nonEmptyString)
上 - 但这个方法有效。

我什至尝试重写

==
运算符以这种方式将字符串与 NonEmptyString 进行比较(我真的没想到这会有所帮助,但值得一试)

public static bool operator ==(string obj1, NonEmptyString obj2)
public static bool operator !=(string obj1, NonEmptyString obj2)
public static bool operator ==(NonEmptyString obj1, string  obj2)
public static bool operator !=(NonEmptyString obj1, string obj2)

我可以做些什么来完成这项工作吗? 预计这不起作用吗? 这是 .NET 中的错误吗?

这是核心实现(我从中删除了不重要的部分。)

public sealed class NonEmptyString : IEquatable<string>, IEquatable<NonEmptyString>
{
    private NonEmptyString(string value)
    {
        Value = value;
    }

    public string Value { get; }

    public static NonEmptyString CreateUnsafe(string value)
    {
        if (string.IsNullOrWhiteSpace(value))
        {
            throw new ArgumentException("You cannot create NonEmptyString from whitespace, empty string or null.");
        }

        return new NonEmptyString(value);
    }

    public override int GetHashCode()
    {
        return Value.GetHashCode();
    }

    public override bool Equals(object obj)
    {
        return ReferenceEquals(this, obj) ||
               obj is NonEmptyString otherNonEmpty && Equals(otherNonEmpty) ||
               obj is string otherString && Equals(otherString);
    }

    public bool Equals(string other)
    {
        return Value.Equals(other);
    }

    public bool Equals(NonEmptyString other)
    {
        return Value.Equals(other?.Value);
    }

    public override string ToString()
    {
        return Value;
    }
}
c# .net string equality iequatable
1个回答
0
投票

我认为这是因为

Equals(object1, object2)
与调用
object1.ReferenceEquals(object2)
相同,并且
ReferenceEquals()
无法被覆盖。

© www.soinside.com 2019 - 2024. All rights reserved.