我实现了一个名为NonEmptyString的类,当它不为空时不允许创建.我让这个类实现了IEquatable<NonEmptyString>
和IEquatable<string>
.我有Equals(object obj)
、Equals(NonEmptyString other)
、Equals(string other)
和GetHashCode()
的覆盖.然后我编写了一些测试,发现几乎所有东西都能正常工作.除了一种情况外,调用静态equals方法时,字符串参数是第一个参数.见this line here.
string text = "ASDF123";
NonEmptyString nonEmptyString = NonEmptyString.CreateUnsafe("ASDF123");
Assert.True(text == nonEmptyString);
Assert.True(nonEmptyString == text);
Assert.True(text.Equals(nonEmptyString)); // This one returns true as expected.
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)
会发生同样的情况--但这一种方法是有效的.这是我进入调用时看到的静态equals的实现.
public static bool Equals(object? objA, object? objB)
{
if (objA == objB)
{
return true;
}
if (objA == null || objB == null)
{
return false;
}
return objA.Equals(objB);
}
我甚至try 用这种方式重写用于比较字符串和非EmptyString的==
个运算符(我真的没想到会有帮助,但值得一试)
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中的错误吗?
以下是核心实现(我go 掉了其中不重要的部分).
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;
}
}