简体   繁体   English

具有泛型类的泛型函数:无隐式引用转换

[英]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.但是方差修饰符仅适用于接口和委托,因此CaCbCc应该是允许这样做的接口。 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.注意CaCb定义中的out T

More about out modifier更多关于输出修饰符

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.

相关问题 C# 通用抽象类 - 没有隐式引用转换 - C# Generic Abstract Class - There is no implicit reference conversion 通用基类的隐式引用转换完成错误 - Implicit Reference Conversion Compliation Error with Generic Base class 通用存储库和通用DbContext中没有隐式引用转换错误 - no implicit reference conversion error in a generic repository and generic DbContext 通用包装器类的隐式C#转换 - Implicit C# Conversion For Generic Wrapper Class C#为泛型类创建隐式转换? - C# creating an implicit conversion for generic class? 返回一个通用的隐式引用 - Return a generic, implicit reference 没有来自……通用查询处理程序cqrs的隐式引用转换。 - There is no implicit reference conversion from… generic query handler cqrs 通用接口具体类型之间没有隐式引用转换错误 - No implicit reference conversion error between generic interface concrete type 尝试使用通用扩展方法时没有隐式引用转换 - No implicit reference conversion when attempting to use generic extension method 通用类型:没有从ToolStripStatusLabel到Control的隐式引用转换 - Generic Types: There is no implicit reference conversion from ToolStripStatusLabel to Control
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM