[英]Generic function with generic class: no implicit reference conversion
I'm trying to cleanup some duplicate code blocks by introducing a generic function.我试图通过引入通用函数来清理一些重复的代码块。 But I don't manage to do so and I have the feeling that my class inheritance structure is becoming messier than the code I'm trying to clean...
但我没能做到,而且我感觉我的类继承结构比我试图清理的代码更混乱......
Here's an abstract overview of the classes involved:以下是所涉及类的抽象概述:
interfaces:接口:
interface Ia
interface Ib : Ia
interface Ic : Ib
classes:类:
class Ca<T> where T : Ia
class Cb<T> : Ca<T> where T : Ia
class Cc : Cb<Ic>
function:功能:
void F<T>(T t) where T : Ca<Ib>
invalid function call:无效的函数调用:
F<Cc>(my_c);
error:错误:
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>'.
I guessed the word 'implicit' in the error my refer to the fact that there is no where T : Ib
in the class definitions.我在错误中猜到了“隐式”这个词,我指的是在类定义中没有
where T : Ib
的事实。 So I added another class所以我添加了另一个类
class Cb2<T> : Cb<T> where T : Ib
and made Cc
inherit from Cb2
instead of Cb
.并使
Cc
继承自Cb2
而不是Cb
。 But this resulted in the same error.但这导致了同样的错误。
Can anyone explain why this is restricted, and how I could solve it?谁能解释为什么这是受限的,我该如何解决?
Thanks!谢谢!
In general C# doesn't alow generic parameter substitution even if they are inherited classes.一般来说,C# 不允许泛型参数替换,即使它们是继承类。 This changed when variance modifiers were added.
添加差异修饰符后,这种情况发生了变化。
What you need is called covariance it enables using derived types in place of generic parameter.您需要的是协方差,它允许使用派生类型代替泛型参数。 But variance modifiers work only on interface and delegates so
Ca
, Cb
, Cc
should be interfaces to allow this.但是方差修饰符仅适用于接口和委托,因此
Ca
, Cb
, Cc
应该是允许这样做的接口。 So closest you can get with it is:所以你能得到的最接近的是:
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);
}
}
Notice out T
in Ca
and Cb
definition.注意
Ca
和Cb
定义中的out T
To make this code works, you'll need to use a interface to enable covariance as Pavel said before.为了使这段代码起作用,您需要使用一个接口来启用协方差,正如 Pavel 之前所说的那样。 You need only one at highest level.
您只需要一个最高级别的。
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>
The method signature should be this way方法签名应该是这样的
void F<T>(T t) where T : ICa<Ib>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.