C# 从具有更具体泛型的子级强制转换为具有不太具体型的父级

C# cast from child with more specific generic to parent with less specific generic

提问人:Montana 提问时间:2/7/2023 更新时间:2/7/2023 访问量:42

问:

我正在尝试从具有特定泛型的子项转换为具有更通用泛型的父项。

采用以下代码:

public class AParent { }
public class AChild : AParent { }

public interface IParent<T>
{
    public void func(T input);
}

public class Child : IParent<AChild>
{
    public void func(AChild input) { }
}

public static void test()
{
    IParent<AParent> parent = new Child();
}

在此代码中,我有 和 where 继承自 。AParentAChildAChildAParent

我还有一个接受泛型类型参数并继承自特定类型的 .IParentChildIParentAChild

我觉得这应该在逻辑上起作用吗?但是我收到以下错误:

Cannot implicitly convert type 'Child' to 'IParent<AParent>'. An explicit conversion exists (are you missing a cast?)

我也尝试将 / 关键字添加到类型参数中,但无济于事。我想做的事情可能吗?这似乎是合乎逻辑的,我错过了什么?inoutTIParent

C# 继承转换 协方差逆

评论

0赞 Montana 2/7/2023
嗯,也许这是一个简单的答案,我只需要一个明确的演员阵容
1赞 Jeppe Stig Nielsen 2/7/2023
不,只有当有人编写了一个实现两者的类时,显式强制转换才能成功,这里的情况并非如此。IParent<AChild>IParent<AParent>
1赞 Jeremy Lakeman 2/7/2023
Child.func()需要 的实例。不能将 的实例强制转换为 的变量。这意味着您不能强制转换函数,也不能强制转换接口。因为这将允许您破坏 .net 的类型安全。AChildAParentAChild
0赞 Montana 2/7/2023
@JeremyLakeman 你是对的。感谢您指出这一点,这似乎是我忽略的部分。谢谢

答:

1赞 Jeppe Stig Nielsen 2/7/2023 #1

此通用接口:

public interface IParent<T>
{
    public void func(T input);
}

type 参数仅用作“input”。因此,将其声明为逆变接口是合法的,如下所示:T

public interface IParent<in T>
{
    public void func(T input);
}

这允许对你想要的内容进行相反的转换:

IParent<AGrandchild> parent = new Child();

其中 是继承 .AGrandchildAChild


当“in”使用 时,使接口协变 (“”) 是不合理的。outT