我正在制作一个自定义字符串类。(主要是出于自我教育的目的——我知道我不会想出比普通string
课程更好的东西,而我不能像使用扩展方法那样轻松地做到这一点。)我在测试时遇到了一个奇怪的问题我的单元测试中的平等。它几乎在所有方面都有效,除了一个。这是单元测试:
MyString myStr = "MyNewString";
Assert.AreEqual("MyNewString", myStr); //Fails
Assert.AreEqual(myStr, "MyNewString");
Assert.IsTrue(myStr.Equals("MyNewString"));
Assert.IsTrue(("MyNewString").Equals(myStr));
Assert.IsTrue(myStr == "MyNewString");
Assert.IsTrue("MyNewString" == myStr);
string realString = "MyNewString";
Assert.AreEqual(realString, myStr); //Fails
Assert.AreEqual(myStr, realString);
Assert.IsTrue(myStr.Equals(realString));
Assert.IsTrue(realString.Equals(myStr));
Assert.IsTrue(myStr == realString);
Assert.IsTrue(realString == myStr);
.ToString()
在这两种失败的情况下,如果我添加after它将成功myStr
,但在任何其他情况下都不需要这样做。我猜这是因为string
'sEquals
方法不知道我的类,即使我已经设置了隐式转换。类的相关部分如下:
public struct MyString : ICloneable, IComparable<MyString>, IComparable<string>,
IEnumerable<char>, IEquatable<MyString>, IEquatable<string>
{
private char[] text;
//Constructors
...
public static implicit operator MyString(string s)
{
return s == null ? null : new MyString(s);
}
public static implicit operator string(MyString s) { return s.ToString(); }
public static bool operator ==(MyString a, MyString b) { return a.Equals(b); }
public static bool operator !=(MyString a, MyString b) { return !(a.Equals(b)); }
public static bool operator ==(MyString a, string b) { return a.Equals(b); }
public static bool operator !=(MyString a, string b) { return !(a.Equals(b)); }
public static bool operator ==(string a, MyString b) { return b.Equals(a); }
public static bool operator !=(string a, MyString b) { return !(b.Equals(a)); }
public override string ToString() { return new string(text); }
public override bool Equals(object obj)
{
if (obj == null)
return false;
if (base.Equals(obj))
return true;
if (obj is MyString)
return this.Equals((MyString)obj);
if (obj is string)
return this.Equals((string)obj);
return false;
}
public bool Equals(MyString other) { return this.CompareTo(other) == 0; }
public bool Equals(string other) { return this.CompareTo(other) == 0; }
}
也有CompareTo()
适用于两者MyString
和常规string
的,但请相信我,它们有效。我还能做些什么来使这个平等测试起作用吗?它似乎在除此之外的所有其他情况下都有效。我不确定Assert.AreEqual
内部实际上是如何运作的,但是如果所有其他测试相等性的方法都有效,那么为什么这个方法会失败?
编辑:添加我的 GetHashCode() 因为它可能是相关的:
public override int GetHashCode()
{
int hash = 0;
for (int i = 0; i < Length; i++ )
hash ^= (i * this[i]);
return hash;
}
当然这可能不匹配string.GetHashCode()
,但我无法知道,因为我看不到他们的代码。(我可以看到元数据,但它只包括标题而不包括实现。)尝试用一个快捷方式替换它string.GetHashCode()
:
public override int GetHashCode()
{
return new string(text).GetHashCode();
}
还是不行。还尝试添加扩展方法:
public static bool Equals(this string a, MyString b) { return b.Equals(a); }
那也没有用。还有其他想法吗?