继承

时间:2018-05-18 22:19:36

标签: c# generics inheritance

我不认为我想要的是可能的,但我希望有人可以验证这一点,也许可以解释为什么不可能。

我们有Bar<T>的继承,我们无法触及Bar<T>

的源代码
abstract class Foo<T> : Bar<T>

我们提供Foo<T>由第三方实施,我们还想要规定从Foo<T>继承的任何类都是T的指定类型。 这当然可以由第三方手动完成,例如

class Fizz : Foo<Fizz>

然而,我发现重复Fizz繁琐而丑陋。 是否可以让Foo<T>自动使用Fizz作为T的指定类型? 换句话说,是否可以让Foo<T>在这些方面实施某些内容

abstract class Foo : Bar<T>
    where T : "Whatever class inherits from Foo"

...我不相信是可能的,因为我找不到合适的泛型类型约束。 是否可以做这样的事情

[SomeBlackMagic("Dear compiler, T is whatever inherits from Foo.")]
abstract class Foo : Bar<T>

...这样Fizz的实现可能只是

class Fizz : Foo

4 个答案:

答案 0 :(得分:2)

这可能不是您想要的,但是您是否考虑过在Foo<T>上实施界面,以便始终确定通用T的类型是什么?

public class Bar<T>
{}

public interface IDev
{}

public abstract class Foo<T> : Bar<T> where T : IDev
{}

public class Fizz : Foo<Fizz>, IDev
{}

它可以让你控制传入的通用对象。

答案 1 :(得分:2)

这就是所谓的Curiously Recurring Template Pattern。不幸的是,大多数强类型语言都无法消除这种代码味道。 C#没有办法改进这一点。

您可以使用运行时检查,但代价是编译时检查。此外,您实际上不会在类接口中使用该类型。例如,您将无法执行abstract class Foo<T> { public T Bar() { ... } }之类的操作,因为编译器不会知道T

答案 2 :(得分:2)

  

我们还想要规定从Foo继承的任何类都是T的指定类型。

此要求可以作为自定义Roslyn分析器实现。

虽然遗憾的是这篇文章abstract class Foo : Bar<T>不可能,但T通用参数应该按某种类型关闭,或者Foo也必须是通用的。

答案 3 :(得分:0)

abstract class Foo<T> : Bar<T>
    where T : Foo<T>
{ /* ... */ }

class Fizz : Foo<Fizz>
{ /* ... */ }

我知道这不是你想要的,但它是最好的选择。