Преобразовать EqualityComparer<Child <T >> в EqualityComparer<Parent>
У меня есть такая иерархия:
public interface INode
{
//...
}
public interface INode<T> : INode
{
//...
}
public class Node : INode
{
//...
}
public class Node<T> : Node, INode<T>
{
//...
}
Теперь я хочу сыграть так:
EqualityComparer<INode<int>> intcomparer = EqualityComparer<INode<int>>.Default;
EqualityComparer<INode> comparer = intcomparer;
Почему этот кастинг недействителен? и как это исправить?
1 ответ
Почему актерский состав должен быть действительным?
Что заставляет вас верить в это EqualityComparer<T>
происходит от EqualityComparer<Random base class/interface of T>
или же EqualityComparer<every possible base class/interface of T>
?
Вы не можете сравнить это с этим:
Node<string> stringNode;
Node node = stringNode;
Это работает, так как ваш класс Определение Node<T>
явно вытекает из неуниверсальной версии Node
public class Node<T> : Node, INode<T>
Когда вы посмотрите на определение класса EqualityComparer<T>
public abstract class EqualityComparer<T> :
System.Collections.Generic.IEqualityComparer<T>,
System.Collections.IEqualityComparer
Вы можете видеть, что нет неуниверсальной версии, вы можете изменить свой код на его:
EqualityComparer<INode<int>> intcomparer = EqualityComparer<INode<int>>.Default;
IEqualityComparer comparer = intcomparer;
Но, IEqualityComparer
не будет никакой информации о вашем INode
и только определить Equals(object, object)
метод.
Это действительно для каждого общего класса, например. увидеть этот связанный, возможно, даже дублирующий вопрос:
Присвоить универсальный
Обновить:
После, заметив, что IEqualityComparer<T>
определяется как IEqualityComparer<in T>
- так что контравариантность возможна, вы можете взглянуть на это:
Дисперсия в универсальных интерфейсах
Возможен и другой способ обойти вас, с интерфейсами IEqualityComparer<T>
не работает в классе.
IEqualityComparer<INode> comparer = EqualityComparer<INode>.Default;
IEqualityComparer<INode<int>> intcomparer = comparer;