我为什么要在这里加倍演员?

时间:2012-05-02 16:52:43

标签: vb.net generics inheritance .net-3.5 casting

我有继承结构:Foo实现IGraphNode继承IGraphItem

FooIGraphItem / IGraphNode以及IGraphItem / IGraphNode的实施都位于不同的程序集中。我正在使用控件容器的反转,因此我正在使用的项目引用前两个(FooIGraphItem / IGraphNode),但不是{的实现{1}} / IGraphItem。我也有Option Strict,因为它是这个项目所需要的(如果关闭则不能解决问题)。我正在使用.NET 3.5。

我正在传递IGraphNode,我的代码如下:

IGraphItem

知道我为什么要这样做?我应该补充说Public Sub ProcessItem(of IGraphItem)(item As IGraphItem) If TypeOf item Is Foo Then Dim f1 = CType(item, Foo) 'Compiler error Dim f2 = DirectCast(item, Foo) 'Compiler error 'This is what I'm currently having to do. It works. Dim f = CType(CType(item, IGraphNode), Foo) 'Do stuff End If End Sub 有效,但由于我们刚刚确认TryCast的类型为item,我不明白为什么我不能Foo它。如果我错了,它不应该让我抛出异常吗?有没有更好的方法来完成我想要做的事情?

2 个答案:

答案 0 :(得分:2)

即使目标框架为3.5,您的原始代码也会毫无问题地编译。

您当前代码的问题在于您已定义了通用方法,而IGraphItem不是您的接口类型,而是通用类型T,可以是任何类型。但它不能是T以外的其他类型,并且您尝试将其强制转换为Foo类型。

如果您要将方法签名更改为其他任何可行的方法,例如:

Public Sub ProcessItem(of IGraphItm)(item As IGraphItem)

我假设你在这个方法中用通用类型IGraphItem以某种方式“遮蔽”你的接口类型IGraphItem

如果您明确告诉编译器item As IGraphItem实际上是item As YourNamespace.IGraphItem,那么它也会有效。

我确信Jon或Eric可以更好地解释它,但无论如何它可能有用;)

答案 1 :(得分:1)

本文可能会回答您的问题。如果没有,那么,无论如何,这是一个很好的阅读。 http://blogs.msdn.com/b/ericlippert/archive/2009/03/19/representation-and-identity.aspx