c # обобщение на метод с ограничением, что тип должен иметь тип "this" - PullRequest
1 голос
/ 20 января 2011

У меня есть иерархия классов C # с общим базовым типом и двумя производными типами.Я хочу объявить абстрактный метод для базового класса примерно так:

public abstract IEnumerable<T> GetSiblings<T>() where T : MyBaseClass

... и я хочу, чтобы этот метод был реализован в производных классах так, чтобы T был типом этого производного типа,для каждого из производных типов, то есть в производном классе A:

public override IEnumerable<A> GetSiblings<A>() { ... }

... и в производном классе B ...

public override IEnumerable<B> GetSiblings<B>() { ... }

Другими словами, каждый производный классдолжен реализовать метод так, чтобы он возвращал IEnumerable элементов того же типа.Есть ли способ реализовать это в C #?

Ответы [ 4 ]

2 голосов
/ 20 января 2011

Что ж, вы вряд ли сможете вызвать универсальный метод, если он принимает параметр только одного типа, а сигнатуры вашего метода будут иметь разные возвращаемые типы, что недопустимо. Почему бы вам не определить интерфейс для всех этих классов и просто вернуть IEnumerable<IMyClass>?

0 голосов
/ 20 января 2011

Я нашел решение. Очевидно в C # 4.0, универсальные типы параметров могут быть ковариантными, так что то, что я опубликовал выше, будет работать. C # 3.5 или ниже, и это не работает. Взял много погуглить.

0 голосов
/ 20 января 2011

Это не поддерживается системой типов.Это достаточно распространенная проблема, часто представляемая как

class Animal<T> where T : Animal<T> { }
class Cat : Animal<Cat> { } // what you desire
class Dog : Animal<Cat> { } // what is possible yet not desired

Но это не та проблема, над которой до сих пор сталкивались соответствующие стороны (будь то провайдеры фреймворков или команда C #, не знаю, кто).

Пока он не пройдет критический тест «стоит», который определяется стоимостью (и альтернативными издержками) в сравнении с выгодами, вам придется обходить его.

0 голосов
/ 20 января 2011

Вы не можете сделать это, потому что типы возврата отличаются.Просто как тот.Причина в том, что если вы создадите экземпляр A и вставите его в базовый класс (приведете его), тогда тип возвращаемого значения будет неправильным.

Возможно, вы сможете использовать вместо него новый, но это может нарушить вашу иерархию.

...