C# 将对象指定给具有父参数化类型的父类型

C# 将对象指定给具有父参数化类型的父类型,c#,generics,C#,Generics,下面是示例代码: public interface C1 { } public class C2 : C1 { } public interface MK<T> { } public struct MKSub : MK<C2> { } public class Test { void Something() { MK<C1> test = new MKSub(); // Somehow make it so this wi

下面是示例代码:

public interface C1 { }
public class C2 : C1 { }

public interface MK<T> { }

public struct MKSub : MK<C2> { }

public class Test
{
    void Something()
    {
        MK<C1> test = new MKSub(); // Somehow make it so this will work?
    }
}
公共接口C1{}
公共类C2:C1{}
公共接口MK{}
公共结构MKSub:MK{}
公开课考试
{
使某物无效
{
MK test=new MKSub();//以某种方式使其生效?
}
}
是否有办法修改此选项,以便注释行上的赋值可以工作


如果不是参数化类型
MK test=new MKSub()当然可以。但是,是否可以对泛型类型声明或其他操作执行某些操作,以使上述赋值也起作用?

您可以在界面上使用协方差运算符
out

public interface C1 { }
public class C2 : C1 { }

public interface MK<out T> { }   // use <out T> instead of <T>

public struct MKSub : MK<C2> { }

public class Test
{
    void Something()
    {
        MK<C1> test = new MKSub();    // this compiles
    }
}
公共接口C1{}
公共类C2:C1{}
公共接口MK{}//使用代替
公共结构MKSub:MK{}
公开课考试
{
使某物无效
{
MK test=new MKSub();//编译
}
}

协方差和逆变是泛型,这是一个太大的主题,在这个答案中无法解释,但您可以阅读更多关于它的内容

只有当您的界面
MK
仅将
T
用作任何方法的输出,而不将其用作输入时,您才能这样做。然后你可以这样做:

public interface MK<out T> {
    T MakeT<Q>(Q other) where Q : T;
}
公共接口MK{
T市场(Q其他),其中Q:T;
}
但是,如果您尝试这样做

public interface MK<out T> {
    void ConsumeT(T val);
}
公共接口MK{
无效消耗量(T val);
}
您将得到一个编译时错误:

协变类型参数
T
必须在
Test.MK.ConsumeT(T)


工作得很好。我就是找不到那个接线员是什么。谢谢