gpt4 book ai didi

c# - 如何检查适用于字符串的通用对象是否相等

转载 作者:太空宇宙 更新时间:2023-11-03 21:46:50 25 4
gpt4 key购买 nike

我今天在重构一些代码时遇到了一些非常奇怪的行为。

我有一些代码看起来像这样:

    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”)视为相等。

看过以下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);
}

嘿 presto - 一切正常,测试再次通过

最佳答案

您可以使用 Object.Equals :

return NullOrCheck(value, v => object.Equals(v, expected));

stringoverloads静态 ==运算符来比较它的两个字符串参数是否相等,即

string first = "abc";
string second = "abc";

bool eq = first == second;

调用==将使用重载的 ==对于字符串,因为 first 的静态类型和 second都是string .

然而,在

object first = "abc";
object second = "abc";
bool eq = first == second;

==使用的运算符将由 object 定义因为 first 的静态类型和 second是对象。请注意,在这种情况下,由于字符串实习,firstsecond实际上将包含对同一字符串的引用,但通常情况并非如此。

在通用方法中,==将解析为静态 ==object 定义而不是为 string 定义的更具体的版本.自 ==是对 object 的简单引用相等性检查s,这表现不同。

Equals方法是虚拟的,可以重写以专门对自定义类型进行相等性检查。因此在

object first = "abc";
object second = "abc";
bool eq = first.Equals(second);

string.Equals 方法将被调用,它将检查字符串是否具有相同的值,而不仅仅是相同的引用。

静态 object.Equals 方法使用虚拟 Equals实例方法,因此它还将检查字符串是否具有相同的值,而不是仅仅指向相同的字符串实例。静态object.Equals还检查其参数是否为空,因此比调用 objA.Equals(objB) 更安全直接。

关于c# - 如何检查适用于字符串的通用对象是否相等,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16542844/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com