我在一个文件/类中遇到了以下代码。我省略了细节,它是我感兴趣的构造。为什么同一个类有两个不同的声明,它们有什么不同?第二个声明的语法的目的是什么?
public abstract class MyClass
{
...
}
public abstract class MyClass<TMyClass> : MyClass
where TMyClass: MyClass<TMyClass>
{
...
}
我在一个文件/类中遇到了以下代码。我省略了细节,它是我感兴趣的构造。为什么同一个类有两个不同的声明,它们有什么不同?第二个声明的语法的目的是什么?
public abstract class MyClass
{
...
}
public abstract class MyClass<TMyClass> : MyClass
where TMyClass: MyClass<TMyClass>
{
...
}
MyClass
- 一个名为 MyClass 的抽象类。
MyClass<TMyClass> : MyClass
- 一个名为的抽象泛型类MyClass<>
,但具有名为 的泛型类型TMyClass
。
如果重命名类型,将更容易看到:
public abstract class MyBaseClass
{
...
}
public abstract class MyClass<T> : MyBaseClass
where T: MyClass<T>
{
...
}
具有不同泛型数量的类型(即泛型类型参数的数量,可以是零或更多)被认为与语言完全无关并且可以具有相同的名称。
这意味着您可以同时拥有课程Foo
;语法将允许编译器确定您指的是哪个。您可以在包含等的基本框架中看到这种情况。Foo<T>
Foo<T,U>
Action
Action<T>
“递归”构造class C<T> where T: C<T>
(从非泛型继承C
并没有改变任何东西,所以我删除了它)是 C# 中所谓的 C++ 中的奇怪循环模板模式(CRTP)。Eric Lippert在一篇博客文章中很好地涵盖了这个主题,其中的结论是在实施之前应该三思而后行——它可以解决一些问题,但解决方案也有代价。
public abstract class MyClass<TMyClass> : MyClass
where TMyClass: MyClass<TMyClass>
{
...
}
是一个继承自 的类,MyClass
它需要一个泛型类型,它必须继承自MyClass<TMyClass>
这是一个更简单的例子
public static void Main()
{
MyClass<Myclass> other = new MyClass<Myclass>(new Myclass());
List<int> intlist = new List<int>();
}
public class Myclass
{
public Myclass()
{
}
public int i { get; set; }
}
public class MyClass<T> where T : Myclass
{
T value;
public MyClass(T val)
{
value = val;
}
}
}
这是一个经典的成语,Curiously Recurring Template Pattern,用 C# 完成。
这意味着模板只能这样使用:
class Foo : MyClass<Foo>
{
}
在这种构造中,Foo
继承MyClass<Foo>
哪个继承MyClass
。
这有一些优点,但我忘记了。
public abstract class MyClass<TMyClass> : MyClass
where TMyClass: MyClass<TMyClass>
{
...
}
首先要指出的是,这是一个继承自另一个抽象类的抽象类。换句话说,这是一个无法实例化的类(没有另一个类从它继承),而是使用继承从另一个抽象类派生功能(这很好)。
要指出的第二件事是,这是一个 Template 类(或在 C# 中调用它的泛型类),它接受它的 . 我会将其简化为 T 作为约定,以便 T 始终是一个模板,尽管这完全取决于您如何称呼事物。
最后,对此有一个限制,这有点奇怪。它说,无论如何,编译器都不允许任何类类型作为模板类型传入,除非它继承自(沿继承链的某处)
MyClass<TMyClass>
这显示在以下行中
where TMyClass: MyClass<TMyClass>
基本上,这可以防止任何人传入不遵循此规则的对象。
有点奇怪的是,约束告诉实现者它不能是模板,除非模板传递的类型实际上是它自己的类型。你作为这个类的设计者(或实现者)必须决定这是否是一个明智的设计,尽管这本身看起来有点奇怪。