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

私の問題は、私が書いたときにコンパイラが正しいインポート関数を決定できないことです:

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、またはそれらの組み合わせ (2D max) の場合は別のコードが必要です。

私の問題を解決するアイデアはありますか?各タイプ (文字列、整数など) およびリストと配列の組み合わせに対して Import 関数をコーディングすることはしません。

ありがとう

4

4 に答える 4

0

私が提供する1つの注意は、配管を考えすぎないことです。

サポートできる特定の型のインポートを実行する方法を知っている場合は、インポート用のインターフェイスを宣言することを検討してから、具体的なクラスに変換を処理できる型を実装させてから、インターフェイス型を関数のパラメーターにします。 IImportable(たとえば)。

編集:もう少し明確にする

IImportableなどのインターフェイスを使用すると、これらのインポート定義を次のように減らすことができます。

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

インターフェイスを実装するための抽象基本クラスを記述してから、インポートできるようにするタイプごとに具体的な実装を記述することもできます。

ちょっと考えてみてください...それがお役に立てば幸いです。

于 2012-09-16T16:35:19.043 に答える
0

コンパイラが引数の型を推測できない場合、少しヒントを与える必要があります。これを試して:

Dim ArrayList As List(Of String)()
Module1.Import(Of List(Of String))(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

1D と 2D 配列 (またはリスト) を区別したくない場合、コンパイラは常に正しい関数を見つけます。2Dでも1Dでもサブならなんとかなると思います。

このトピックを閉じる前にさらにテストしますが、今のところは問題ありません。

于 2012-09-17T06:26:23.383 に答える
0

(少なくとも) 1 つのオーバーロードの名前を変更して、IList インターフェイスの Add および AddRange と同様の方法で名前を付けることができます。リフレクションまたは動的言語機能を使用していない限り、呼び出すメソッドの選択はコンパイル時の決定になります。コードを呼び出すメソッドは、 だけではなく、常に 1 つの特定のオーバーロードを毎回参照します。ただし、そのコードを記述するときに、どのオーバーロードを使用するかを考えず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
于 2012-09-16T17:38:03.820 に答える