0

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

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))

我的问题是编译器在我编写时无法确定正确的 Import 函数:

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...但如果它是 Array、List 或它们的组合(最大二维),我需要不同的代码。

那么你有什么想法来解决我的问题吗?我不会为每种类型(字符串、整数、...)以及列表和数组的组合编写导入函数。

谢谢

4

4 回答 4

0

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

将 ArrayList 调暗为列表(字符串)()
Module1.Import(列表(字符串))(ArrayList)
于 2012-09-16T18:53:41.377 回答
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

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

在结束这个话题之前我会测试更多的东西,但目前还可以。

于 2012-09-17T06:26:23.383 回答
0

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

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

编辑:更多澄清

使用 IImportable 之类的接口,您可以将这些 Import def 减少到:

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

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

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

于 2012-09-16T16:35:19.043 回答
0

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

If you are aiming for dynamic usage, you may be best having an Import method that accepts an object parameter, and then implementing your own type checking of that object to decide which of the existing methods to use for the import, thus allowing you to decide your own order of preference when the interpretation of the input instance is otherwise ambiguous. You would then be able to just call your method with any input (even at runtime) and have it choose your preferred import method. I seem to remember that the typeof keyword was made a lot more efficient back when generics were introduced in .NET2 so it might not be as bad a solution as you might initially assume would be the case by avoiding at least some of the generics.

有关 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
于 2012-09-16T17:38:03.820 回答