Вы можете использовать абстрактный базовый класс плюс явную реализацию члена для достижения этой цели.Сначала объявите ваш интерфейс следующим образом:
interface IFoo
{
IFoo Bar();
}
Затем объявите обобщенный абстрактный класс, который явно реализует IFoo, а также объявите абстрактный метод, который как бы «перегружает» Bar (), но вуниверсальный способ:
abstract class BaseFooImpl<T> : IFoo where T : BaseFooImpl
{
public abstract T Bar();
IFoo IFoo.Bar()
{
return Bar(); // this will call the abstract Bar()
}
}
Теперь определите ваши конкретные классы следующим образом:
class ConcreteFoo : BaseFooImpl<ConcreteFoo>
{
public override ConcreteFoo Bar()
{
return this; // for example, of course.
}
}
Преимущество этого подхода в том, что вы всегда можете использовать неуниверсальные ссылки IFooдержать конкретные экземпляры .Если вы сделаете свой интерфейс универсальным, вы не сможете, например, объявить следующее:
IFoo mammalInstance, fishInstance; // Instead of IFoo<Mammal> mammalInstance; IFoo<Fish> fishInstance;
List<IFoo> manyInstances; // Instead of List<IFoo<IFoo>>, which doesn't even work AFAIK