Ответ 1
Работа с дженериками без знания общих типов параметров
При использовании CRTP полезно иметь неосновный базовый класс (абстрактно, если это возможно, но это не так уж важно), наследуемый вашим базовым классом. Затем вы можете создавать абстрактные (или виртуальные) функции в своем базовом классе и не допускать, чтобы потребительский код работал с вашими объектами, не зная общих параметров. Например:
abstract class NonGenBase
{
public abstract void Foo();
}
class GenBase<T>: NonGenBase
{
public override void Foo()
{
// Do something
}
}
Теперь потребляющий код, который не знает, что T должен быть, может по-прежнему вызывать процедуру Foo() на ваших объектах, рассматривая их как экземпляры базового класса.
Как решить задачу наследования статического поля
При использовании CRTP для решения проблемы часто полезно предоставлять доступ к статическим полям при наследовании классов. Проблема в том, что С# не позволяет наследовать классы, чтобы иметь доступ к этим статическим полям, кроме как через имя типа... которое часто, кажется, побеждает цель в этой ситуации. Возможно, вы не сможете придумать ясный пример того, о чем я говорю, и объяснение того, что это выходит за рамки этого ответа, но решение прост, поэтому просто уберите его в своей базе знаний и когда вы найдете в нем потребность вы будете этому рады:)
class GenBase<T>: NonGenBase
{
static object _someResource;
protected object SomeResource { get { return _someResource; } }
}
Это "имитирует" наследование статических полей. Однако имейте в виду, что статические поля в общем классе не охвачены всеми вашими универсальными реализациями. Каждая родовая реализация имеет свой собственный экземпляр статического поля. Если вы хотите, чтобы одно статическое поле было доступно для всех реализаций, вам просто нужно добавить его в свой не общий базовый класс.