Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/335.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#铸造通用型<;B>;到通用<;A>;B:A在哪里_C#_Generics_Type Conversion - Fatal编程技术网

C#铸造通用型<;B>;到通用<;A>;B:A在哪里

C#铸造通用型<;B>;到通用<;A>;B:A在哪里,c#,generics,type-conversion,C#,Generics,Type Conversion,我有两个班,我的班A和班B。MyClassB继承自MyClassA。我已经用下面的签名写了一个方法 public void DoSomething(MyGeneric<MyClassA> obj); public void DoSomething(MyGeneric obj); 我还有以下事件处理程序 public void MyEventHandler(Object source, EventArgs e) { //source is of type MyGeneric&

我有两个班,我的班A和班B。MyClassB继承自MyClassA。我已经用下面的签名写了一个方法

public void DoSomething(MyGeneric<MyClassA> obj);
public void DoSomething(MyGeneric obj);
我还有以下事件处理程序

public void MyEventHandler(Object source, EventArgs e)
{
   //source is of type MyGeneric<MyClassB>
   DoSomething((MyGeneric<MyClassA>)obj);
}
public void MyEventHandler(对象源,事件参数e)
{
//源的类型为MyGeneric
剂量测定法((MyGeneric)obj);
}
我知道
MyGeneric
不是同一类型的
MyGeneric
,但是既然MyClassB是MyClassA的一个子类,还有什么方法可以让它工作呢

为供参考,确切的错误消息如下:

无法强制转换类型为的对象 'MSUA.GraphViewer.GraphControls.TreeNode
1[MSUA.GraphViewer.GraphControls.materialconfiggcontrol]'
打字
'MSUA.GraphViewer.GraphControls.TreeNode
1[MSUA.GraphViewer.PopulatableControl]'


这是泛型中的类型逆变

即使
B
a
的一个子类型,
Generic
不是
Generic的子类型以了解详细信息


您可以将
DoSomething()
重载为
DoSomething(Generic)
,然后此方法可以将
Generic
转换为
Generic
,并调用
DoSomething(Generic)
大多数泛型类都有一个cast函数为您执行此操作。如果它不存在,您可以尝试创建自己的。

如果您的泛型类
MyGeneric
可以实现在
t
中协变的
接口,那么您可以执行以下操作:

public void MyEventHandler(object source, EventArgs e)
{
    DoSomething((IMyGeneric<MyClassA>)source); //IMyGeneric<MyClassB> is implicitly convertible to IMyGeneric<MyClassA>
}
  • T
    中定义接口协变项:

    public interface IMyGeneric<out T>
    {
        T Foo();
    }
    
    因此,在您的情况下,您可以编写以下内容:

    public void MyEventHandler(object source, EventArgs e)
    {
        DoSomething((IMyGeneric<MyClassA>)source); //IMyGeneric<MyClassB> is implicitly convertible to IMyGeneric<MyClassA>
    }
    
    public void MyEventHandler(对象源,事件参数e)
    {
    DoSomething((IMyGeneric)source);//IMyGeneric隐式转换为IMyGeneric
    }
    

  • 编辑:只需阅读您正在使用.NET 3.5的评论,不幸的是,这在您的情况下不起作用。我会留下答案,以防对别人有用。对不起,我错过了那条重要的信息。

    大部分?我不知道“大多数泛型类都有强制转换函数”。我知道有一个为序列定义的
    Cast
    扩展方法试图强制转换序列中的每个项。你的答案似乎暗示它几乎是默认的泛型模式的一部分。基本上,将泛型转换为泛型将意味着,泛型(),但这不会有帮助,不是吗,因为B被转换为A,但仍然是B。总之,答案很好,你绝对正确,但是要解决这个问题会很困难。他还可以尝试将
    MyGeneric
    更改为接口类型,如
    IEnumerable
    。这行吗?@Roy T你可以试试
    隐式运算符
    @StuperUser,我来看看隐式运算符。同样需要注意的是,在VS2010中,您在中使用了通用的逆变修饰符:这允许逆变,但不幸的是,我仍然停留在2008/.NET3。5@oleksii:这是因为
    IEnumerable
    T
    中是协变的(参见下面我的答案)。遗憾的是,这仅在.NET4.0中可用。在.NET3.5中,该代码将无法编译。这仍然是一个很好的答案,它将解决我在2010年遇到的问题,而我忘记在实际问题中提到我被困在2008/.NET.3.5:)