我已經定義了一個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;
}
}
現在,我想能夠直接比較這個類與任何其他字符串(對象或文字)。所以,我實現了在類以下內容:
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);
}
現在,當我寫一個單元測試,具體取決於我傳遞的參數Assert.AreEqual的順序上,我得到不同的結果:
string valid = "Some String";
field target = new field(valid);
Assert.AreEqual(target, valid); // PASSES
Assert.AreEqual(valid, target); // FAILS
我假設這是因爲在第一個斷言,它調用field.Equals()和在第二個它調用String.Equals()。很明顯,我從錯誤的角度來看待這個問題。任何人都可以給我一些見解嗎?
另一件事。我不能在這裏使用結構(值類型),因爲在我的實際情況中,我將所有這些定義在基類中並從中繼承。
+1像這樣的類型使用起來很棘手,而且要讓其他人一致地使用它們會很棘手。在實體本身中保留驗證和其他業務邏輯更好。 – 2009-04-27 00:34:40
不幸的是我使用這個類的實例作爲字典和集合等中的鍵。我需要Equals()和GetHashCode()的行爲類似值類型,以便他們在這些情況下正確工作。 – 2009-04-27 01:10:38
覆蓋Equals(),你可能想考慮實現IComparable http://msdn.microsoft.com/en-us/library/system.icomparable.aspx 我真的希望MS會把操作符重載出c#。 – 2009-04-27 01:32:00