[英]Generic function with generic class: no implicit reference conversion
我试图通过引入通用函数来清理一些重复的代码块。 但我没能做到,而且我感觉我的类继承结构比我试图清理的代码更混乱......
以下是所涉及类的抽象概述:
接口:
interface Ia
interface Ib : Ia
interface Ic : Ib
类:
class Ca<T> where T : Ia
class Cb<T> : Ca<T> where T : Ia
class Cc : Cb<Ic>
功能:
void F<T>(T t) where T : Ca<Ib>
无效的函数调用:
F<Cc>(my_c);
错误:
The type 'Cc' cannot be used as type parameter 'T' in the generic type or method 'F<T>(T)'. There is no implicit reference conversion from 'Cc' to 'Ca<Ib>'.
我在错误中猜到了“隐式”这个词,我指的是在类定义中没有where T : Ib
的事实。 所以我添加了另一个类
class Cb2<T> : Cb<T> where T : Ib
并使Cc
继承自Cb2
而不是Cb
。 但这导致了同样的错误。
谁能解释为什么这是受限的,我该如何解决?
谢谢!
一般来说,C# 不允许泛型参数替换,即使它们是继承类。 添加差异修饰符后,这种情况发生了变化。
您需要的是协方差,它允许使用派生类型代替泛型参数。 但是方差修饰符仅适用于接口和委托,因此Ca
, Cb
, Cc
应该是允许这样做的接口。 所以你能得到的最接近的是:
interface Ia {}
interface Ib : Ia {}
interface Ic : Ib {}
interface Ca<out T> where T : Ia {}
interface Cb<out T> : Ca<T> where T : Ia {}
interface Cc : Cb<Ic> {}
class Main
{
void F<T>(T t) where T : Ca<Ib>
{}
void M()
{
F<Cc>(null);
}
}
注意Ca
和Cb
定义中的out T
为了使这段代码起作用,您需要使用一个接口来启用协方差,正如 Pavel 之前所说的那样。 您只需要一个最高级别的。
interface ICa<out T> where T : Ia
class Ca<T> : ICa<T> where T : Ia
class Cb<T> : Ca<T> where T : Ia
class Cc : Cb<Ic>
方法签名应该是这样的
void F<T>(T t) where T : ICa<Ib>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.