存储实现多个接口并从某个基础派生的对象(.net) [英] Storing an object that implements multiple interfaces and derives from a certain base (.net)

查看:213
本文介绍了存储实现多个接口并从某个基础派生的对象(.net)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在.net中,可以使用泛型,以便函数可以接受支持一个或多个接口的参数并从基类型派生,即使不存在所有有效参数类型派生的任何单一类型。例如,可以说:

In .net, it's possible to use generics so that a function can accept arguments which support one or more interfaces and derive from a base type, even if there does not exist any single type from which all valid argument types derive. For example, one could say:

Sub Foo(Of T As {IInterface1, IInterface2, SomeBaseType})(Param as T)

并允许传递SomeBaseType的任何衍生物,它实现了IInterface1和IInterface2。即使SomeBaseType不支持Interface1和Interface2,这也会起作用,并且实现这些接口的类不共享任何也实现它们的共同祖先。

and be allowed to pass any derivative of SomeBaseType which implements both IInterface1 and IInterface2. This will work even if SomeBaseType does not support Interface1 and Interface2, and classes which do implement those interfaces don't share any common ancestor that also implements them.

这可以是如果在退出函数后不需要将参数保留在任何地方,这非常方便。不幸的是,我无法找到一种方法来保持传入的参数,以便以后可以将其传递给类似的函数,除非使用Reflection。有没有什么好办法呢?

This can be very convenient if one won't need to keep the parameter anywhere after the function has exited. Unfortunately, I can't figure out a way to persist the passed-in parameter in such a way that it can later be passed to a similar function, except perhaps by using Reflection. Is there any nice way of doing that?

我能想到的最接近的是定义一个接口INest(也许不是最好的名字 - 可以有人改进吗?)因此:

The closest I've been able to come up with is to define an interface INest (perhaps not the best name--can anyone improve it?) thus:

Interface INest(Of Out T)
    Function Nest() As T
End Interface

以及任何将与其他接口或基类一起使用的接口约束,定义如下图所示的通用版本

And for any interface that will be used in combination with others or with base-class "constraint", define a generic version as illustrated below

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

一个支持多个接口的类应该将自己声明为实现泛型的,将其自身作为类型参数。

A class which will support multiple interfaces should declare itself as implementing the generic ones, with itself as the type argument.

Class test123a
    Inherits sampleBase
    Implements IFun1(Of test123a), IFun2(Of test123a), IFun3(Of test123a)
End Class

如果这样做,可以定义一个支持多个约束的函数参数或类变量:

If that is done, one can define a function argument or class variable that supports multiple constraints thusly:

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的一个实现。

and then assign to it any class derived from sampleBase, which implements those interfaces. SomeField will implement IFun1; SomeField.Nest will implement IFun2; SomeField.Nest.Nest will implement IFun3. Note that there's no requirement that IFun1, IFun2, IFun3, or sampleBase share any common derivation other than the generic interfaces inheriting from INest(Of T). Note also that, no matter how many INest-derived interfaces a class implements, it only needs to define one implementation of INest(Of T).Nest.

不完全漂亮但是有两个很好的事情:(1)实际上实现必要接口的任何具体类都可以直接分配给上面声明的字段,而不需要进行类型转换; (2)虽然以不同顺序链接类型的字段不是赋值兼容的,但它们可能相互转换。

Not exactly beautiful, but there are two nice things about it: (1) any concrete class which in fact implements the necessary interfaces can be assigned directly to a field declared as above, without a typecast; (2) while fields which chain the types in a different order are not assignment compatible, they may be typecast to each other.

有没有更好的方法来存储内容这样一种方式,它已知支持多个接口并从某种基类型派生?鉴于可以以类型安全的方式编写此类代码,如果编译器提供了一些帮助,那么.net 2.0 CLR似乎可以很好地支持这样的事情。不过,我现在还没有意识到现有编译器的任何特别好的方法。

Is there any better way to store something in such a way that it's "known" to support multiple interfaces and derive from a certain base type? Given that one can write such code in a type-safe manner, it would seem like the .net 2.0 CLR could probably support such a thing quite nicely if compilers offered a little assistance. I'm unaware of any particularly nice approach with present compilers, though.

推荐答案

我能想到的最好的方法是制作此存储的抽象存储和通用实现。例如(原谅我的VB.NET):

The best way I can think of is to make an abstract storage and generic implementation of this storage. For example (excuse my VB.NET):

MustInherit Class Storage
    Public MustOverride Sub DoSomething()
End Class

Class Storage(Of T As {IInterface1, IInterface2, SomeBaseType})
    Inherits Storage

    Public Overrides Sub DoSomething()
        ' do something with Value.
    End Sub

    Public Value As T
End Class

和用法

Dim S As Storage

Sub Foo(Of T As {IInterface1, IInterface2, SomeBaseType})(ByVal Param As T)
    S = New Storage(Of T) With {.Value = Param}
End Sub

Sub UseS()
    S.DoSomething();
End Sub

更新:好的,因为我们可能没有能够事先识别所有操作:

Update: Ok, because we may not be able identify in advance all of the actions:

MustInherit Class Storage
    MustOverride ReadOnly Property SomeBaseType As SomeBaseType
    MustOverride ReadOnly Property IInterface1 As IInterface1
    MustOverride ReadOnly Property IInterface2 As IInterface2
End Class

Class Storage(Of T As {IInterface1, IInterface2, SomeBaseType})
    Inherits Storage

    Public Value As T

    Public Overrides ReadOnly Property IInterface1 As IInterface1
        Get
            Return Value
        End Get
    End Property

    Public Overrides ReadOnly Property IInterface2 As IInterface2
        Get
            Return Value
        End Get
    End Property

    Public Overrides ReadOnly Property SomeBaseType As SomeBaseType
        Get
            Return Value
        End Get
    End Property
End Class

这篇关于存储实现多个接口并从某个基础派生的对象(.net)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆