Проблема в том, что ваш абстрактный метод Compare
определен для принятия параметра типа Class1<T>
и возврата экземпляра Class1<T>
, , а не более конкретного типа, чем Class1<T>
.Но это то, что пытается сделать ваш Class3.Compare
метод: вызовите T.Compare
и предположите, что результат будет T
, хотя на самом деле вы можете быть уверены, что это будет Class1<U>
.
Чтобы предоставить более простой и понятный пример, предположим, что у меня был этот класс:
class Parser
{
public abstract object Parse(string text);
}
class Int32Parser
{
public int Parse(Parser parser, string text)
{
return parser.Parse(text);
}
}
Приведенный выше код делает ошибочное предположение похожим на ваше: что parser.Parse
вернет int
только потому, что1020 * происходит от object
(как и в вашем случае, T
должно происходить от Class1<U>
);на самом деле, вы можете быть уверены, что он вернет object
.
Существует два способа решения этой проблемы: сделать Class1<T>.Compare
универсальным методом:
public abstract U Compare<U>(U otherObj) where U : Class1<T>;
... или ослабьте специфику типа возвращаемого значения вашего Class3.Compare
метода:
public Class1<U> Compare(T obj1, T obj2)
{
// ...
}
Лично я предпочел бы второе, если вам абсолютно не нужно первое.Все эти ограничения общего типа могут стать очень грязными и обременять вас больше, чем вы ожидаете, когда сложность начинает расти таким образом.