У меня есть общий 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.
Теперь, когда я пытаюсь использовать:
BinarySearchTree<EnglishDictionaryWord> _tree =
new BinarySearchTree<EnglishDictionaryWord>();
Я получаю ошибку компиляции:
Тип «DsLib.EnglishDictionaryWord» нельзя использовать в качестве параметра типа «T» в универсальном типе или методе «DsLib.BinarySearchTree». Не существует неявного преобразования ссылок из «DsLib.EnglishDictionaryWord» в «System.IComparable».
Если я попытаюсь сделать
public class BinarySearchTree<T> : ICollection<T> where T : IComparable<T>
тогда я получаю эту ошибку компиляции о том, что преобразование в бокс недоступно.
Тип 'T' нельзя использовать в качестве параметра типа 'T' в универсальном типе или методе 'DsLib.BinaryTreeNode'. Конвертирование или преобразование параметров типа из 'T' в 'System.IComparable' не выполняется.
У меня есть 2 вопроса:
(1).
Я запутался в реализации дженериков. Может ли какая-нибудь деталь как это исправить? и общая схема, чтобы избежать таких ошибок в будущем.
Когда использовать IComparable<T>
, а когда IComparable
.
(2). Является ли этот шаблон компаратора корректным, имея компаратор внутри класса dataitem? Потому что пользователь предоставит новый EnglishWord
для вставки в дерево. Он потенциально может использовать разные компараторы для каждого слова. Тогда оно сломает дерево.
РЕДАКТИРОВАТЬ: Добавлен код класса BSTNode
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; }
}