我想实现一个通用的C#类,其大致如下:
abstract class Foobar<T> : AbstractBase, T
{ ... }
这失败了,因为C#只允许基类之后的类型成为接口,所以接下来我试试这个:
abstract class Foobar<T> : AbstractBase, T where T : interface
{ ... }
但后来我发现C#不允许这种形式的类型约束。仅允许where T : struct
和where T : class
。
如何指示类型参数只能是接口类型?
答案 0 :(得分:6)
基本上,你不能。
您可以对特定接口进行约束,但不能对所有接口进行通用约束。因此,您可以约束IEnumerable,但不能任何接口。
无论如何你还需要这个吗?
答案 1 :(得分:4)
该代码的真正问题在于您是从类型参数继承的。
尝试编译
abstract class Foobar<T> : T { ... }
仍然会失败:错误CS0689:无法从'T'派生,因为它是一个类型参数。
我认为这至少在抽象类的情况下是完全合理的,我也想要这个功能,但是c#编译器不会让你这样做。
答案 2 :(得分:1)
你不能用简单的话说。
答案 3 :(得分:1)
我相信你误解了where T : struct
和where T : class
的含义。
这样的通用type constraint表示T
必须分别是值类型或引用类型。
但是,界面的目的是定义 契约 ,与值类型与引用类型语义相比,这是一个完全不同的概念。
因此,像where T : interface
这样的限制毫无意义。
如果您想了解更多信息,我建议您阅读关于类型约束的C#编程指南:
<强> Constraints on Type Parameters (C# Programming Guide) 强>
答案 4 :(得分:0)
这会失败,因为C#只允许基类之后的类型为接口
此约束是由于C#中缺少多重继承。可以通过使用接口来近似多重继承,因为重写方法是显式的。一个类只能扩展另一个类,但可以实现多个接口。这里的技巧是实现类必须为方法定义主体,以便实现特定于调用哪个方法。
使用where限制T可以应用于一个类或多个接口。您不能将范围限制为几个类。