c# - 强制执行通用接口(interface)子类型

标签 c# .net generics inheritance interface

我有一个通用接口(interface) ( MyInterface<T> ),它由类 ChildA 实现在下面的示例中:

public interface MyInterface<T>
{
    MyObj<T> GetObj(); // Irrelevant
}

class ChildA : MyInterface<ChildA>
{
    // Irrelevant:
    MyObj<ChildA> GetObj() {
        return new MyObj<ChildA>();
    }
}

这有效,但我需要确保 <T>始终具有实现 类的类型,因此在本例中为 T应始终为 ChildA 类型, 因为它是由 ChildA 实现的.

另一个正确的实现可能是这样的,例如:

class ChildB : MyInterface<ChildB> { ... }

但目前,这种不正确 实现也是可能的,但它不应该:

class ChildA : MyInterface<ChildB> { ... }

有没有办法强制执行此操作?

最佳答案

您不能强制将泛型类型参数限制为实现类型。

可用type constraints以下是:

  • where T : struct
  • where T : class
  • where T : new()
  • where T : <base class name>
  • where T : <interface name>
  • where T : U

没有什么比where T : self在 C# 中。实际上,它甚至没有意义,因为这样的事情无法有意义地执行。此外,它根本不符合协变/逆变概念,并且一般来说从中继承会很奇怪。

您可以做的最接近的事情是:

public interface IMyInterface<T> where T : IMyInterface<T>
{
    MyObj<T> GetObj();
}

为什么没有意义

假设您可以这样做:

public interface IMyInterface<T> where T : self // this syntax does not exist in C#
{
    MyObj<T> GetObj();
}

现在所有的实现类型都必须使用它们自己作为类型参数。但您仍然可以这样做:

public class ChildC<T> : IMyInterface<T> where T : self
{
    /* ... */
}

这将绕过您的限制。

关于c# - 强制执行通用接口(interface)子类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38743196/

相关文章:

c# - 如何获取类型的默认泛型委托(delegate)

.net - 如何监控 MVC4 中的异步/等待死锁?

.net - 如何从引用的 .NET 程序集中重新导出类型

java - Java 中的新 <T>

Java 扩展泛型

c# - 来自 NAudio 的原始音频

c# - BigInteger 解析八进制字符串?

c# - 无法将 keyValuePair 直接添加到 Dictionary

c# - ABCPdf 使用大量内存并生成巨大文件。解决方案?

c# - 为什么 Generic Casting 不适用于这部分代码?