C#铸造通用型<;B>;到通用<;A>;B:A在哪里
我有两个班,我的班A和班B。MyClassB继承自MyClassA。我已经用下面的签名写了一个方法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&
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.TreeNode1[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:)