.net 用哪一个?此场景中的i可比较通用或非通用

.net 用哪一个?此场景中的i可比较通用或非通用,.net,generics,collections,.net,Generics,Collections,我有一个通用BST和一个dataItem类作为treeNode的值 public class BinarySearchTree<T> : ICollection<T> where T : IComparable { } public class EnglishDictionaryWord : IComparer<EnglishDictionaryWord>, IComparable<EnglishDictionaryWord> {

我有一个通用BST和一个dataItem类作为treeNode的值

public class BinarySearchTree<T> : ICollection<T>  where T : IComparable
{

}

public class EnglishDictionaryWord
    : IComparer<EnglishDictionaryWord>, IComparable<EnglishDictionaryWord>
{
    public EnglishDictionaryWord(string word, WordCompareType type)
    {
        Word = word;
        Length = Word.Length;
        _compareType = type;
    }

    public int Compare(EnglishDictionaryWord x, EnglishDictionaryWord y)
    {
        if (_compareType == WordCompareType.Length)
            return new WordLengthComparer().Compare(x, y);
        else if (_compareType == WordCompareType.Lexical)
            return new WordLexicalComparer().Compare(x, y);
        else
            throw new InvalidOperationException("Unsupported Comparison type");
    }

    public int CompareTo(EnglishDictionaryWord obj)
    {
        return Compare(this, obj);
    }
} 

public class WordLengthComparer : IComparer<EnglishDictionaryWord>
{
    public WordLengthComparer()
    {

    }
    public int Compare(EnglishDictionaryWord x, EnglishDictionaryWord y)
    {
        return x.Length - y.Length;
    }
}

and similar Lexical comparer class.

您还需要更改
BinaryTreeNode

public class BinaryTreeNode<T> where T : IComparable<T>
公共类二进制树节点,其中T:IComparable

我使用以下定义尝试了您的代码:

  public class BinarySearchTree<T>
      : ICollection<T>
      where T : IComparable<T>

  public class EnglishDictionaryWord
      : IComparer<EnglishDictionaryWord>,
        IComparable<EnglishDictionaryWord>

  public class WordLengthComparer
      : IComparer<EnglishDictionaryWord>
公共类二进制搜索树
:i收集
其中T:i可比较
公共级英语词典
:I比较者,
不可比
公共类字长比较器
:I比较
它工作得很好-它编译、执行等等。。。(.NET 4.0,c#)):

BinarySearchTree\u树=
新的二进制搜索树();
并回答您的其他问题:

  • 你应该总是喜欢
    IComparable
    而不是
    IComparable
    。它更快,更不容易出错(无铸造/装箱/拆箱)等。。。至于你的问题:为什么需要它?很简单,
    IComparable
    IComparable
    是不同的类型(它们有相似的名称,但不要让这混淆了您的意思,它们的类型是不同的)。因此,您只需在引用的任何位置放置相同的类型

  • 插入到树中的数据应该具有比较逻辑。当您定义树时,您可以精确地指定它将使用的项的类型-因此,只要该对象存在,您就不能向其中添加完全不同的类型。例如,如果您定义了:

    BinarySearchTree\u树

  • 您无法向
    \u tree
    添加其他内容,如
    SpanglishDictionaryWord
    ,因此树确实保持了正确的结构,因为只添加了
    EnglishDictionaryWord
    的项,并且它们定义了一致的结构和比较逻辑

    编辑我刚才看到您有一个“Has”比较器逻辑,而不是纯粹的“Is”可比。这应该是固定的(从数据项中删除对比较器的引用)-如果不是,您是对的-树可能会被破坏

    EDIT2如果您需要数据项具有灵活的比较逻辑(即改变比较它们的方式,这很奇怪,请仔细想想),那么BST必须有一个对您打算与之一起使用的比较器实例的引用:或者将包装比较器的项与实际项放在一起,或者将项的比较器作为BST的属性,并在决定转到哪个分支时在每个数据项上使用它

    如果我在与树相关的类/方法中的任意位置更改为
    IComparable
    ,它都会编译。为什么需要这样做

    IComparable
    不继承自
    IComparable

    第二个问题呢


    你说得对-如果不同的项目有不同的排序类型,列表将出现故障。更好的模式是让类型拥有一个默认的排序行为,然后允许集合接受并使用备用的IComparers。要了解这一点,请检查

    的重载,我看不到
    DsLib.BinaryTreeNode的任何地方…@Kamarey我的问题是关于IComparable和IComparable而不是IComparaler,IComparabrei也这样做了。同样的错误。还有一个问题是为什么?需要对所问问题进行一些解释。@Daniel是的,谢谢。如果我在树相关的类/方法中更改为IComparable everywhere,它就会编译。那很好。你能回答为什么需要这样做以及第二个问题吗?我主要是想了解原因,而不是在将来尝试错误:)+1代表“Has”。“Is”。请看我对@David B答案的评论。在这一部分增加你的答案。谢谢。你是说TreeOfEnglishWords.OrderBy(new WordLengthComparer())之类的?我的树在添加/包含操作期间也需要比较器。那么树是否应该在其构造函数中接受默认比较器呢?是的,构造函数。类似于泛型词典如何在其构造函数中接受IEqualityComparer。
    public class BinaryTreeNode<T> where T : IComparable
    {
        public BinaryTreeNode(T value)
        {
            Value = value;
        }
    
        public T Value { get; protected internal set; }
        public BinaryTreeNode<T> Right { get; protected internal set; }
        public BinaryTreeNode<T> Left { get; protected internal set; }
        public BinaryTreeNode<T> Parent { get; protected internal set; }
    
        public int Height { get; protected internal set; }
    }
    
    public class BinaryTreeNode<T> where T : IComparable<T>
    
      public class BinarySearchTree<T>
          : ICollection<T>
          where T : IComparable<T>
    
      public class EnglishDictionaryWord
          : IComparer<EnglishDictionaryWord>,
            IComparable<EnglishDictionaryWord>
    
      public class WordLengthComparer
          : IComparer<EnglishDictionaryWord>
    
     BinarySearchTree<EnglishDictionaryWord> _tree = 
         new BinarySearchTree<EnglishDictionaryWord>();