2014-06-13 177 views
1

我试图能够将一个Type参数传递给名为ConvertList的函数,并让该函数创建指定类型的某些实例。所以,如果我传入Foo类型,函数将创建Foo类型的新对象,并将创建的对象放入自定义List对象(SLMR_OBjList)中。将参数传递给泛型类型VB.Net中的新构造函数泛型

功能是定义一个通用类:

Public Class BOIS_Collection_Base(Of T) 

功能将接受比什么是类定义了其他类型。所以,如果我们创建一个BOIS_Collection_Base(Of MyTypeA)的实例,我们可以调用函数ConvertList(Of MyTypeB)

我想私有变量_convertedList是一个不同于类的类型。这可能吗?我似乎只能用(T)来定义它。

这是我到目前为止有:

Public Class BOIS_Collection_Base(Of T) 
    Private _convertedList As SLMR_ObjList(Of T) ' I can only seem to define this as (Of T), but want to make sure I can pass in a Type other than the Base(Of T) 
    Public Function ConvertedObjList(Of myT)() As SLMR_ObjList(Of T) ' Should this be (Of T) or (Of myT) since I want it to use whatever Type is passed in 
     For Each tempVar In Me.ObjList 
      Dim newitem As myT = Activator.CreateInstance(GetType(myT), tempVar) 
      ' Next line won't compile, says on newitem 'Value of type 'myT' cannot be converted to 'T' 
      _convertedList.Add(newitem) 
     Next 
     _convertedList.Sort_Direction = Me.Sort_Direction 
     _convertedList.Sort_Expression_List = Me.Sort_Expression_List 
     Return _convertedList 
    End Function 

这里是我想能够做到:

Dim mainCollInstance As New BOIS_Collection_Base(Of MyTypeA) 
.... 
'Code that populates the BOIS_Collection_Base.ObjList property with an SLMR_ObjList(Of MyTypeA) 
.... 
' Now I want to take that ObjList, and cast all the items in it to MyTypeB 
Dim newListObj As SLMR_ObjList(Of MyTypeB) = mainCollInstance.ConvertList(Of MyTypeB) 

这可能吗?我错了吗?

针对Plutonix:
如果我定义_convertedList的方法中,像这样:

Public Function ConvertedObjList(Of myT)() As SLMR_ObjList(Of myT) 
    Dim _convertedList = New SLMR_ObjList(Of myT) 

我的错误去了,和方法我想要做什么,但_convertedList不再是持续性的目的。

+0

我不确定这是泛型的问题,但你如何实现继承。如果'MyTypeA'和'MyTypeB'相关,那么集合类可能应该是'(Of AB_BaseClass)'。更重要的是,如果他们是相关的,那么它应该很容易从另一个自己创建一个实例:'newItem = New myTypeA(myTypeB)' – Plutonix

+0

我不知道我明白了。请查看更新。 –

+2

如果你想保存它,这意味着你总是将相同的类型传递给'ConvertedObjList(Of T)'函数,对吧? –

回答

1

如果您想保留列表,那么您无法真正让消费代码每次都为列表传递不同的类型。这并没有多大意义,除非每次调用它时,只需要该函数返回包含给定类型对象的持久列表部分。如果是这种情况,那么您只需声明_convertedList As SLMR_ObjList(Of Object),然后过滤它并根据需要将其转换为正确的类型。如果,但是,如果我怀疑是这种情况,消费者总是会要求在每次调用该函数时将其转换为相同类型,那么该输出类型实际上并不是函数调用的属性。相反,它是全班的财产。在这种情况下,你应该让你的类需要两个泛型类型参数,就像这样:

Public Class BOIS_Collection_Base(Of T, TOut) 
    Private _convertedList As SLMR_ObjList(Of TOut) 

    Public Function ConvertedObjList() As SLMR_ObjList(Of TOut) 
     For Each tempVar As T In Me.ObjList 
      Dim newitem As TOut = DirectCast(Activator.CreateInstance(GetType(TOut), tempVar), TOut) 
      ' Next line won't compile, says on newitem 'Value of type 'myT' cannot be converted to 'T' 
      _convertedList.Add(newitem) 
     Next 
     _convertedList.Sort_Direction = Me.Sort_Direction 
     _convertedList.Sort_Expression_List = Me.Sort_Expression_List 
     Return _convertedList 
    End Function 
End Class 
0

基于前人的有关问题和假设MyTypeA和MyTypeB从同一类继承(没有得到回答)你可能不需要这种泛型。无论如何,这应该有助于问题的部分。我还未看到泛型适合,因为继承可以做你想做什么就:

Class MustInherit BiosItem 
    Public Property Name As String 
    Public Property TypeCode As String 
    ... 
    MustOverride Function Foo(args...) As Type 

    Overridable Property FooBar As String  
    ' etc - the more stuff in the base class the better 

End Class 
Class TypeA 
    Inherits ABClass 

    Public Sub New 
     MyBase.New  ' stuff common to all child types 
     TypeCode = "A" ' EZ type ID rather than GetType 
     ... 
    End Sub 
End Class 

类的TypeB是相同的,但初始化类型码为“B”。对于C-Z也是如此。这些允许您轮询对象而不需要GetType:If thisObj.TypeCode = "A" Then...。现在,集合类:

Public Class BIOSItems 
    Inherits Collection(Of BiosItem) 
    ' inheriting from Collection<T> provides Add, Count, IndexOf for us 
    ' most important the Items collection 
    ' 
End Class 

键入集合作为BiosItem将允许它TypeATypeJTypeQ。原样,您的收藏将仅保留一个类型。这是有效的,因为GetType(TypeA)的项目也是GetType(BiosItem)。最后请参阅注释。

将一个项目转换为另一个项目看起来似乎很大程度上将由正在创建或转换为的NEW项目处理。因为他们很可能是非常相似的话,就可以通过一个构造函数重载来处理(如果它们不相似,以及我们非常走上错误的道路):

' a ctor overload to create the new thing based on the old things props 
Public Sub New(oldThing As BiosItem) 
    MyClass.New   ' start with basics like TypeCode, MyBase.New 

    With BiosItem   ' coversion 
     myFoo = .Foo 
     myBar = .Bar  ' copy common prop vals to self 
     ... 
     Select Case .TypeCode 
      Case "B" 
       myProp1 = .Prop33  ' conversions 
       myProp3 = .Prop16 + 3.14 
       ... 
     End Select 

     ' then initialize stuff unique to this type maybe 
     ' based on other props 
     If .PropX = "FooBar" Then myPropZ = "Ziggy" 
    End With 
End Sub 

代码来创建,转换,存储:

Dim varOldBItem As TypeB = myBiosCol(ndx) ' get old item 
Dim varAItem As New TypeA(varOldBItem)  ' call the ctor above 
myBiosCol.Add(varAItem)      ' add new item 
myBiosCol.Remove(varoldBItem)    ' delete the old if need be 

如果BOIS_Collection_Base总是应该包含MyTypeA,然后键入它的方式(从Collection<T>继承,以便似乎仍然)。如果MyTypeB对象永远不会直接添加到集合中,但首先将其转换为MyTypeA(Edit会使这一点不那么清晰),但上述大部分仍然适用,但继承除外。 MyTypeA上的一个ctor过载仍然可以使用一个旧的B对象并基于它创建它自己。如果不从同一个基类继承,我不会倾向于通过ctor来完成,但可以完成。

相关问题