【问题标题】:Can I dictate that a C# type parameter must only be an interface type?我可以规定 C# 类型参数只能是接口类型吗?
【发布时间】:2010-10-11 10:59:39
【问题描述】:

我想实现一个通用的 C# 类,大致如下:

abstract class Foobar<T> : AbstractBase, T
{ ... }

这失败了,因为 C# 将只允许基类之后的类型作为接口,所以接下来我试试这个:

abstract class Foobar<T> : AbstractBase, T where T : interface
{ ... }

但后来我发现 C# 不允许这种形式的类型约束。仅允许使用 where T : structwhere T : class

如何规定类型参数只能是接口类型?

【问题讨论】:

  • 你想达到什么目的?我真的想不出这种约束是必要的情况。

标签: c# generics type-constraints


【解决方案1】:

基本上,你不能。

您可以对特定接口进行约束,但不能对所有接口进行通用约束。因此,您可以限制为例如 IEnumerable,但不能限制为 any 接口。

你还需要这个做什么?

【讨论】:

  • 我注意到从 Foobar 派生的所有类最终也都实现了 T。我想我可以通过将派生类中的 implements Blah 移动到基类上来强制执行这种情况Foobar。
【解决方案2】:

该代码的真正问题是您从类型参数继承。

尝试编译

abstract class Foobar<T> : T { ... }

仍然会失败:错误 CS0689:不能从 'T' 派生,因为它是一个类型参数。

我认为至少在抽象类的情况下这是完全合理的,我也想要这个功能,但是 c# 编译器不允许你这样做。

【讨论】:

  • +1 用于提及问题的核心(源自类型参数)。
【解决方案3】:

我相信你误解了where T : structwhere T : class的含义。

像这样的通用type constraint 意味着T 必须分别是值类型引用类型

然而,接口的目的是定义一个契约,与值类型和引用类型语义相比,这是一个完全不同的概念。

因此像where T : interface 这样的限制是没有意义的。

如果你想了解更多,我建议你阅读 C# Programming Guide on type constraint:

Constraints on Type Parameters (C# Programming Guide)

【讨论】:

  • 如果存在可用于此类类型且仅可用于此类类型的语言功能,则作为接口类型的约束将是有意义的。例如,如果可以定义一个Wrapper&lt;T&gt;:T where T:interface(Foo),其语义是该类将定义一个T 类型的字段Foo,并显式实现接口m 的每个成员m,这将非常有帮助。通过让它调用Foo.m。即使有 CLR 支持,这样的通用工具也不适用于类,但如果 CLR 提供了必要的特性,它可能对接口非常有用。
【解决方案4】:

你不能用简单的话。

【讨论】:

    【解决方案5】:

    这失败了,因为 C# 将只允许基类之后的类型成为接口

    此限制是由于 C# 中缺少多重继承。多重继承可以通过使用接口来近似,因为覆盖方法是显式的。同理,一个类只能扩展另一个类,但可以实现多个接口。这里的技巧是实现类必须定义方法的主体,以便实现特定于调用哪个方法。

    使用 where 限制 T 可以应用于一个类,也可以应用于多个接口。您不能将范围限制为多个类。

    【讨论】:

      猜你喜欢
      • 2020-10-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-09-23
      • 1970-01-01
      • 1970-01-01
      • 2012-10-25
      相关资源
      最近更新 更多