我在今天遇到了一些非常奇怪的行爲,同時重構了一些代碼。如何檢查泛型對象是否適用於字符串
我有一些代碼,看起來是這樣的:
private AType Blah
{
get
{
return (from something in AList
where _x == null || something.x == _x
where _y == null || something.y == _y
where _z == null || something.z.IsSameAs(_z)
select something).Single();
}
}
我anonomised類型和變量名,因爲它們不是這個問題很重要。
_x和something.x的類型是字符串,_y和something.y是引用類型。同樣,_z和something.z是一個具有值比較的參考類型。
我想我可以做這樣的事情:
public AType Blah
{
get { return AList.Single(something => DetailsMatch(something.x, something.y, something.z)); }
}
private bool DetailsMatch(string x, AnotherType y, AFurtherType z)
{
return NullOrCheck(_x, x) &&
NullOrCheck(_y, y) &&
NullOrCheck(_z, z.IsSameAs);
}
private bool NullOrCheck<T>(T value, T expected) where T : class
{
return NullOrCheck(value, v => v == expected);
}
private static bool NullOrCheck<T>(T value, Func<T,bool> check) where T : class
{
return value == null || check(value);
}
這一切似乎都有道理,但讓我吃驚的一些測試啓動失敗。事實證明,相同的字符串(例如「1A04」和「1A04」)不再被認爲是相等的使用==運算符。
看了下面的Can't operator == be applied to generic types in C#?,似乎可能是字符串在引用相等而不是以正常方式進行比較。
有沒有一種安全的方式來做到這一點在c#中或應該使用==在泛型方法被認爲是危險的上述原因?
只是爲了確認,這是我的修復包括內聯的字符串的情況下違規方法產生的問題:
private bool DetailsMatch(string x, AnotherType y, AFurtherType z)
{
return (_x == null || _x == x) &&
NullOrCheck(_y, y) &&
NullOrCheck(_z, z.IsSameAs);
}
變戲法似的 - 一切工作和測試再次通過
它似乎也有工作要做:v.Equals(預期)。看起來像一個非常奇怪的修復,因爲你會認爲如果使用較少的派生==,那麼相同的情況對於等於也是如此。或者我在這裏錯過了什麼? – 2013-05-14 12:30:26
@JonnyLeeds - '=='是一個靜態運算符,因此根據其參數的靜態類型進行解析。 「Equals」是一個虛擬方法,在運行時解析。靜態Object.Equals方法也檢查它的參數爲null,所以'Equals(null,someObject)'返回false,而null.Equals(someObject)'在運行時拋出一個異常。 – Lee 2013-05-14 12:34:02
你可以擴展一下 - 我聽說過以前的靜態類型的短語,但沒有正確解釋它。順便說一句,知道內置於Equals中的空檢查 - 大概這意味着你可以進一步簡化這個方法 – 2013-05-14 12:38:15