C#泛型,比较两个字符串失败,除非明确指定

8

我以为我已经见过所有的东西,但是这个... :)

我正在处理一个字符串类型的通用图表,

Graph<string> graph = new Graph<string>();

图表的类约束声明如下:

public class Graph<T> where T : class

下一步,我将用一些动态生成的字符串填充图表:
for (char t = 'A'; t < 'J'; t++)
{
    GraphPrim.Add(t.ToString());
}

目前为止一切顺利,(Node是一个内部类,包含原始值和对其他节点的引用(因为它是一个图))

现在,当我尝试在不同节点之间创建关系时,我必须通过检查其值来查找正确的节点,这就是问题所在。

以下代码是在进行一些测试后在立即窗口中得到的结果的直接副本:

Nodes.First().Value
"A"
Nodes.First().Value == "A"
false
Nodes.First().Value.ToString() == "A"
true

我是完全错过了什么吗?或者Nodes.First().Value == "A"不应该使用字符串比较方法。(JIT编译器对运行时使用的类型及其支持的方法有了解,对吗?)我觉得当没有明确指定一个字符串时,它会执行引用检查而不是字符串测试。如果有人能向我解释一下这个问题,那就太好了。提前致谢!

3
Value 属性的静态类型是什么? - Mehrdad Afshari
你确定Value被定义为:public T Value { get; set; } - albertein
3个回答

8

如果类型不能在前期完全确定(例如,Value 只以 T 的形式存在,并且不是严格已知的字符串),可以使用以下方法:

object.Equals(Nodes.First().Value,"A")

当然,你可以进行强制类型转换,但在这种情况下,你需要使用双重转换 ((string)(object)),这看起来很丑陋。

如果你知道两个对象是相同类型的 (即两个T值),那么你可以使用:

EqualityComparer<T>.Default.Equals(x,y)

上述方法的优点在于避免了结构体的装箱操作,并支持可提升的Nullable<T>运算符和IEquatable<T>,此外还包括Equals

5
如果您的节点的Value属性是object,则在JavaScript中使用==运算符时,它将比较对象的引用而不是内容。
Nodes.First().Value == "A"

将会通过引用进行比较,而不是比较字符串。


3

==是一个静态方法,因此不是虚拟的。选择使用哪个==方法是在编译时而不是运行时进行的。根据对象的编译时类型,它可能会选择比较引用的对象的==实现。

如果您改为使用虚拟的Equals方法,则可以按照您的期望工作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接