我正在尝试通过引入通用函数来清理一些重复的代码块。但我没能做到这一点,而且我感觉我的类继承结构变得比我试图清理的代码更困惑......
以下是所涉及的类的抽象概述:
接口(interface):
interface Ia
interface Ib : Ia
interface Ic : Ib
类(class):
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# 不允许泛型参数替换,即使它们是继承的类。当 variance 时,情况发生了变化添加了修饰符。
您需要的称为协方差,它允许使用派生类型代替泛型参数。但方差修饰符仅适用于接口(interface)和委托(delegate),因此 Ca
、Cb
、Cc
应该是允许这样做的接口(interface)。你能得到的最接近的是:
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
。
关于c# - 具有泛型类的泛型函数 : no implicit reference conversion,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31698283/