Здравствуйте, vdimas, Вы писали:
V>Здравствуйте, Pzz, Вы писали:
Pzz>>Мне нравится подход. "Он случайно унаследовал базовый класс от класса наследника.
V>Кривой перевод или журнализд наврал. Это не наследование от наследниника, это использование типа до его определения, но после объявления. Вполне себе практика С/С++ и до всяких шаблонов.
Pzz>>Если это работает и в C#, это не комплимент в пользу C#
V>Но используется аж в самой базовой инфраструктуре стандартных либ, например:
V>https://docs.microsoft.com/ru-ru/dotnet/api/system.iequatable-1?view=netcore-3.0
Ну, с интерфейсом это ещё не так явно проявляется. Более классический случай — наследуемся от класса, получаем в подарок набор статик мемберов, которые невозможно получить "нелюбопытным" наследованием:
public abstract class TaggedString<T> where T : TaggedString<T>, new()
{
protected string _value;
public static T New(string value) => new T{_value = value};
public static T operator +(TaggedString<T> left, string right) => new T { _value = left._value + right };
}
И далее
public class MyString: TaggedString<MyString>{ }
...
var t = MyString.New("Hello");
var p = t + ", world!";