【发布时间】:2011-05-21 08:53:49
【问题描述】:
在 .net 中,可以使用泛型,以便函数可以接受支持一个或多个接口并从基类型派生的参数,即使不存在任何可以派生所有有效参数类型的单一类型。例如,可以说:
Sub Foo(Of T As {IInterface1, IInterface2, SomeBaseType})(Param as T)
并允许传递实现 IInterface1 和 IInterface2 的 SomeBaseType 的任何派生类。即使 SomeBaseType 不支持 Interface1 和 Interface2,这也可以工作,并且实现这些接口的类不共享任何同样实现它们的共同祖先。
如果在函数退出后不需要将参数保留在任何地方,这将非常方便。不幸的是,我想不出一种方法来持久化传入的参数,以便以后可以将其传递给类似的函数,除非可能使用反射。有什么好的方法吗?
我能想到的最接近的方法是定义一个接口 INest(也许不是最好的名字——任何人都可以改进它吗?)因此:
Interface INest(Of Out T)
Function Nest() As T
End Interface
对于将与其他接口或基类“约束”结合使用的任何接口,请定义一个通用版本,如下所示
Interface IFun1
' Any members of the interface go here, e.g. ...'
Sub DoFun1()
End Interface
Interface IFun1(Of Out T)
' This one does nothing but inherit'
Inherits IFun1, INest(Of T)
End Interface
一个支持多个接口的类应该将自己声明为实现泛型接口,并将自己作为类型参数。
Class test123a
Inherits sampleBase
Implements IFun1(Of test123a), IFun2(Of test123a), IFun3(Of test123a)
End Class
如果这样做,可以定义一个支持多个约束的函数参数或类变量:
Dim SomeField as IFun1(Of IFun2(Of IFun3(Of sampleBase)))
然后将任何派生自 sampleBase 的类分配给它,该类实现了这些接口。 SomeField 将实现 IFun1; SomeField.Nest 将实现 IFun2; SomeField.Nest.Nest 将实现 IFun3。请注意,除了从 INest(Of T) 继承的通用接口之外,IFun1、IFun2、IFun3 或 sampleBase 不需要共享任何公共派生。另请注意,无论一个类实现了多少 INest 派生接口,它只需要定义一个 INest(Of T).Nest 实现即可。
不是很漂亮,但它有两个好处:(1) 任何实际上实现了必要接口的具体类都可以直接分配给如上所述声明的字段,而无需进行类型转换; (2) 虽然以不同顺序链接类型的字段不兼容赋值,但它们可以相互类型转换。
有没有更好的方法来存储某些东西,使其“已知”支持多个接口并从某个基本类型派生?鉴于可以以类型安全的方式编写这样的代码,如果编译器提供一点帮助,.net 2.0 CLR 似乎可以很好地支持这样的事情。不过,我不知道目前的编译器有什么特别好的方法。
【问题讨论】:
标签: vb.net inheritance interface .net-2.0 covariance