c# Casting泛型解析:选B

本文关键字:解析 Casting 泛型 Generic | 更新日期: 2023-09-27 18:02:06

我有两个类,MyClassA和MyClassB。MyClassB继承自MyClassA。我写了一个签名为

的方法
public void DoSomething(MyGeneric<MyClassA> obj);

我还得到了以下事件处理程序。

public void MyEventHandler(Object source, EventArgs e)
{
   //source is of type MyGeneric<MyClassB>
   DoSomething((MyGeneric<MyClassA>)obj);
}

我理解MyGeneric<MyClassA>不是同一类型的MyGeneric<MyClassB>,但由于MyClassB是MyClassA的子类,是否仍有方法使此工作?

作为参考,确切的错误消息:

无法强制转换类型的对象'MSUA.GraphViewer.GraphControls.TreeNode 1[MSUA.GraphViewer.GraphControls.MaterialConfigControl]' to type 'MSUA.GraphViewer.GraphControls.TreeNode 1[msua . graphviewer . populatableccontrol]'.

c# Casting泛型<Generic< A>解析:选B

这是泛型中的类型逆变。

尽管BA的亚型,
Generic<B>不是Generic<A>的子类型,
所以你不能将Generic<B>转换为Generic<A>

查看:http://msdn.microsoft.com/en-us/library/dd799517.aspx

可以将DoSomething()重载为DoSomething(Generic<B>),该方法可以将Generic<B>转换为Generic<A>并调用DoSomething(Generic<A>)

如果您的通用类MyGeneric<T>可以实现interface,这是T的协变,那么您可以做以下操作:

  1. T中定义接口协变:

    public interface IMyGeneric<out T>
    {
        T Foo();
    }
    

    这意味着泛型类型T只能作为输出类型(不能作为接口中定义的方法签名的一部分)。

  2. 让你的类MyGeneric<T>实现IMyGeneric<out T>

  3. 现在通过interface,它在T中是协变的,下面的代码是有效的:

    IMyGeneric<MyClassB> classBGeneric = new MyGeneric<MyClassB>();
    IMyGeneric<MyClassA> classAGeneric = classBGeneric;
    

    在你的例子中,你可以这样写:

    public void MyEventHandler(object source, EventArgs e)
    {
        DoSomething((IMyGeneric<MyClassA>)source); //IMyGeneric<MyClassB> is implicitly convertible to IMyGeneric<MyClassA>
    }
    

EDIT:只要在评论中读到你正在使用。net 3.5,所以遗憾的是这在你的情况下不起作用。我将把答案留下,以防对别人有用。对不起,我错过了那条重要的信息。

大多数一些泛型类有强制类型函数。如果它不存在,您可以尝试创建自己的