我正在学习泛型,但有些东西我不明白这里有这个类;
class Node<T>{
T value;
Node <T> next,prev;
public Node(T vl)
{
this.value=vl;
this.next=this.prev=null;
}
}
我有一个类 List 和一个方法 Insert,它工作正常:
class Lista<T>
{
public Node<T> Head, Tail;
public int Cnt;
public Lista()
{
this.Head = this.Tail = null;
this.Cnt = 0;
}
public void Insert(T vl)
{
Node<T> nd = new Node<T>(vl);
if (this.IsEmpty())
this.Head = this.Tail = nd;
else
{
this.Tail.next = nd;
nd.prev = this.Tail;
this.Tail = nd;
}
this.Cnt++;
}
}
但我有一个方法 FindNode:
public Node<T> FindNode(T vl)
{
if (this.IsEmpty()) return null;
Node<T> tmp = this.Head;
while (tmp != null && ((object)tmp.VL != (object)vl)) tmp = tmp.next;
return tmp;
}
现在问题是在列表中找到一个节点
如果我有 Lista<string>
它工作正常,但如果我创建一个 Lista<int>
即使列表中的元素在比较时存在,它也会忽略相同的值并继续下一步直到它变为 null,为什么会发生这种情况?
方法为空:
public bool IsEmpty()
{
if (this.Head == null && this.Tail == null) return true;
return false;
}
最佳答案
问题是,对于像 int
这样的值类型在您的示例中,您通过转换为对象来装箱它们。
默认情况下,==
运算符执行 ReferenceEquality,这意味着在您的情况下它永远不会返回 true,因为 boxes 永远不会相同。
解决这个问题最简单的方法就是转动这条线
while (tmp != null && ((object)tmp.VL != (object)vl)) tmp = tmp.next;
进入这个
while (tmp != null && !Equals(tmp.VL , vl)) tmp = tmp.next;
这将为特定类型使用默认的相等比较器,并使您的代码按预期工作。
您可以更进一步,使用为您的类声明的通用约束,如下所示:
class Lista<T> where T : IEquateable<T>
并像这样更改同一行
while (tmp != null && (!tmp.VL.Equals(vl)) tmp = tmp.next;
或者可以注入(inject) IEqualityComparer<T>
进入你的类(class)
class Lista<T>
{
IEqualityComparer<T> _comparer;
public Lista(IEqualityComparer<T> comparer = null)
{
_comparer = comparer ?? EuqlityComparer<T>.Default;
}
public Node<T> FindNode(T vl)
{
if (this.IsEmpty()) return null;
Node<T> tmp = this.Head;
while (tmp != null && !_comparer.Equals(tmp.VL, vl) tmp = tmp.next;
return tmp;
}
}
关于c# - 为什么在 C# 中将对象转换为具有相同值的类型 T 的对象不被识别为相同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53435912/