c# - 为什么在 C# 中将对象转换为具有相同值的类型 T 的对象不被识别为相同?

标签 c# generics

我正在学习泛型,但有些东西我不明白这里有这个类;

    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/

相关文章:

c# - Garbage Collection和各代阈值

java - 传递给方法的无限通配符

C# 泛型转换

c# - 无法加载文件或程序集“Microsoft.SharePoint,版本=15.0.0.0”

c# - 是否有应用程序国际化的最佳实践方法?

c# - csproj LangVersion 属性覆盖任何导入的项目

c# - 泛型或多个类

Delphi (VCL) 泛型和数据绑定(bind)?

java - 无界通配符参数化类型数组的实际用法是什么?

c# - 从或正则表达式组中获取第一个匹配项