通用类型和覆盖

时间:2012-09-16 16:14:10

标签: .net arrays list generics

我有一个类,我想用这些定义实现一个导入函数:

1. Public Sub Import(of T)(ByRef Data() as T)

2. Public Sub Import(of T)(ByRef Data(,) as T)

3. Public Sub Import(of T)(ByRef Data()() as T)

4. Public Sub Import(of T)(ByRef Data as List(Of T))

5. Public Sub Import(of T)(ByRef Data as List(Of T()))

6. Public Sub Import(of T)(ByRef Data as List(Of List(Of T)))

7. Public Sub Import(of T)(ByRef Data() as List(Of T))

我的问题是编写器在写入时无法确定正确的导入功能:

Dim ArrayList as List(of String)() = something
MyClass.Import(ArrayList)

我理解为什么,因为1和7可以代表相同的事情。

所以我试着在课堂上写作:

Public Sub Import(Of T)(ByRef Data() As T)
    Try
        Select Case True
            Case Data(0).GetType().IsArray
                ImportArrayArrayT(Data)
            Case Data(0).GetType.IsGenericType
                ImportArrayListT(Data)
            Case Else
                ImportArrayT(Data)
        End Select
    Catch ex As Exception

    End Try
End Sub

Protected Sub ImportArrayT(Of T)(ByRef Data() As T)
End Sub

Protected Sub ImportArrayArrayT(Of T)(ByRef Data As T()())
End Sub

Protected Sub ImportArrayListT(Of T)(ByRef Data() As List(Of T))
End Sub

但我在ImportArrayArrayT(Data)ImportArrayListT(Data)ImportArrayT(Data)上收到了其他错误。消息错误表示无法从方法的参数中推断出数据类型。

我需要使用泛型类型,因为我不关心类型是String,Integer,Double ......但是如果它是一个数组,一个List或它们的组合(2D max)我需要不同的代码。

那你有什么想法解决我的问题吗?我不会为每个Type(String,Integer,...)以及List和Array的组合编写Import函数。

由于

4 个答案:

答案 0 :(得分:0)

我要提出的一个警告是不要过度思考管道。

如果您知道如何为您可以支持的特定类型执行导入,请考虑为导入声明一个接口,然后让具体类实现可以处理转换的类型,然后只需将接口键入参数即可函数,例如IImportable(例如)。

编辑:更多澄清

使用IImportable等界面,您可以将导入def减少为:

Protected Sub Import(of T)(ByRef IImportable(Of T))

您甚至可以编写一个抽象基类来实现该接口,然后为您希望能够导入的每种类型编写具体的实现。

只是一个想法......希望它有用。

答案 1 :(得分:0)

您可以更改(至少)其中一个重载的名称,并以与IList接口上的Add和AddRange类似的方式命名它们。除非您使用反射或动态语言功能,否则选择要调用的方法将是编译时决定。调用代码的方法每次都会引用一个特定的重载,而不仅仅是Import,尽管在编写代码时它可能会觉得它是一个动态的选择,因为你只需要在不考虑的情况下编写Import关于你想要使用哪一个。它不像类继承,它可以在编译后根据每个实例的类型继承基类型的方式更改方法的最终选择。因此,您也可以只更改导致冲突的方法的名称。

如果您的目标是动态使用,最好使用接受对象参数的Import方法,然后实现对该对象的自己的类型检查,以决定将哪个现有方法用于import,从而允许您在输入实例的解释不明确时决定您自己的首选顺序。然后,您可以使用任何输入(即使在运行时)调用您的方法,并让它选择您首选的导入方法。我似乎记得在.NET2中引入泛型时,typeof关键字的效率更高,所以它可能不像你最初假设的那样糟糕,至少避免一些仿制药。

有关使用类型,请参阅http://msdn.microsoft.com/en-us/library/0ec5kw18(v=vs.80).aspx。代码看起来像:

If (input Is TypeOf(List(Of T)))
    ' Import somehow'

Else If (input Is TypeOf(ArrayList(Of T)))
    ' Import some other way'

' etc.'
End If

答案 2 :(得分:0)

当编译器无法推断出参数的类型时,你必须给它一点提示。试试这个:

Dim ArrayList As List(Of String)()
Module1.Import(Of List(Of String))(ArrayList)

答案 3 :(得分:0)

感谢您的回答,但我想我已经找到了使用ParamArray的解决方案(晚上是一个很好的帮助!)。如果我使用这个代码似乎很好:

Public Sub Import(Of T)(ByVal ParamArray Data As List(Of T)())
End Sub

Public Sub Import(Of T)(ByVal ParamArray Data()() As T)
End Sub

Public Sub Import(Of T)(ByRef Data(,) As T)
End Sub

Public Sub Import(Of T)(ByRef Data As List(Of List(Of T)))
End Sub

Public Sub Import(Of T)(ByRef Data As List(Of T()))
End Sub

如果我不想区分1D和2D数组(或列表),编译器会在所有情况下找到正确的函数。如果它是2D或1D数据,我想我可以管理子。

在关闭这个主题之前我会测试更多的东西,但目前还可以。