今天我在重构一些代码时遇到了一些非常奇怪的行为。
我有一些看起来像这样的代码:
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();
}
}
我已经对类型和变量名称进行了匿名化,因为它们对问题并不重要。
_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”)是相等的。
看过以下不能将运算符 == 应用于 C# 中的泛型类型?似乎字符串是在引用相等而不是以正常方式进行比较的。
在 c# 中是否有一种安全的方法可以做到这一点,或者由于上述原因,在泛型方法中使用 == 是否应该被认为是危险的?
只是为了确认这是问题,我的修复包括在字符串大小写中内联有问题的方法,导致:
private bool DetailsMatch(string x, AnotherType y, AFurtherType z)
{
return (_x == null || _x == x) &&
NullOrCheck(_y, y) &&
NullOrCheck(_z, z.IsSameAs);
}
嘿 presto - 一切正常,测试再次通过