2012-01-31 16 views
0

私は、の古いデータベースシステムに接続するサードパーティライブラリを使用しています。 「ストアドプロシージャ」を呼び出すメソッド(CallProg)があります(より良い翻訳の欠如のために、群衆のどのピックユーザも?)。しかし、代わりにこのような何かを行うの:オーバーロードされた2つのサブシステムを1つに結合する

Public Sub CallProg(ProgName, ParamArray ProgArgs() As String) 
    ... 
End Sub 

かさえ、この:

Public Sub CallProg(ProgName, Optional Arg1 As String, Optional Arg2 As String ... Optional Arg20 As String) 

彼らはこれをしなかった:

Public Sub CallProg(ProgName) 
Public Sub CallProg(ProgName, Arg1 As String) 
Public Sub CallProg(ProgName, Arg1 As String, Arg2 As String) 
Public Sub CallProg(ProgName, Arg1 As String, Arg2 As String, Arg3 As String) 
... 
Public Sub CallProg(ProgName, Arg1 As String, ... Arg20 As String) 

私は、ログイン処理するための抽象クラスを書いています環境を設定するなど、他の多くのプロジェクトでジェネリックな "ヘルパー"クラスとして使用することができます。 CallProg subに20オーバーロードが含まれないようにする方法はありますか?

+0

あなたが記述した 'Optional'オプションの何が問題になっていますか? – Oded

+0

ヘルパールーチンを20個のオプションを使って作成した場合、私は 'Select Case'ステートメントに20個の' Case'行が必要です。 1つの引数を必要とするバックエンドプログラムに20個の引数をすべて渡すようにしようとしているので、1つの "実際の"引数と20個の空白の文字列で、基礎となる 'CallProg'サブを呼び出すことはできません。 – mounty

+0

私はあなたがリフレクションを使うことができると思います。 –

答えて

0

これは、リフレクションを使用して行う方法の非常に簡単なアイデアです。私はその最良の方法かはわからないが、それは動作するはずです...

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load 

    CallProg("ProgName", {"testArg1", "TestArg2"}) 

End Sub 

Private Sub CallProg(ByVal ProgName As String, ByVal Params As IEnumerable(Of String)) 

    Dim testClass As New Test1 

    Dim methodTypes As List(Of Type) = 
     Params.Select(Function(x) GetType(String)).ToList 

    methodTypes.Add(GetType(String)) 

    Dim methodToBeCalled As Reflection.MethodInfo = 
     testClass.GetType.GetMethod("CallProg", 
            System.Reflection.BindingFlags.Instance Or System.Reflection.BindingFlags.Public, 
            Type.DefaultBinder, 
            methodTypes.ToArray, 
            Nothing) 


    Dim paramsToPass As New List(Of String) 

    paramsToPass.Add(ProgName) 
    paramsToPass.AddRange(Params) 

    methodToBeCalled.Invoke(testClass, paramsToPass.ToArray) 

End Sub 

エンドクラス

パブリック・クラスのTest1

Public Sub CallProg(ByVal ProgName As String) 
    Debug.WriteLine("Sub0 called") 
End Sub 

Public Sub CallProg(ByVal ProgName As String, ByVal Arg1 As String) 
    Debug.WriteLine("Sub1 called") 
End Sub 

Public Sub CallProg(ByVal ProgName As String, ByVal Arg1 As String, ByVal Arg2 As String) 
    Debug.WriteLine("Sub2 called") 
End Sub 

Public Sub CallProg(ByVal ProgName As String, ByVal Arg1 As String, ByVal Arg2 As String, ByVal Arg3 As String) 
    Debug.WriteLine("Sub3 called") 
End Sub 

エンドクラス

+0

これは大雑把にはうまくいったことです。私がやったことも投稿します。 – mounty

0

別の方法にRene147が提案したことを:

Private _act As New APIClass 

Public Sub CallProg(ByVal ProgName As String, ByVal ParamArray ProgArgs() As String) 
    Try 
     Dim tList As New List(Of Type) 
     tList.Add(GetType(String)) 

     Dim aList As New List(Of String) 
     aList.Add(ProgName) 

     For Each arg In ProgArgs 
      tList.Add(GetType(String).MakeByRefType) 
      'tList.Add(GetType(String)) <-- only use this if all the args are ByVal 
      aList.Add(arg) 
     Next 
     Dim typeList As Type() = tList.ToArray 
     Dim argList As String() = aList.ToArray 

     GetType(APIClass).GetMethod("CallProg", typeList).Invoke(_act, argList) 
    Catch ex As Exception 
     Console.Write("Error running program {0}.", ProgName) 
    End Try 
End Sub 
+0

例外をキャッチしてエラーを表示するのは無意味です。例外がスローされると、エラーメッセージが表示されます。 –

+0

実際には、この場合、一度に5つの接続しか許可されない接続マネージャ(ライセンスに関する問題がいくつかあります)を使用しているため、デバッグして例外を逃してプログラムをリセットする必要があります。接続マネージャーに行き、私が手動で使っていた接続を閉じます。例外をキャッチすることで、クラスを正常にログアウトさせることができます(ここでは表示されません)。しかし、私は同意します - 通常の状況下では、必要ではないでしょう。 – mounty

+0

気まぐれです。プログラムが*閉鎖*されていることに気づいていませんか?コンポーネントを切り替える時間、それは明らかに行き詰まりです。いずれにしても、ハックとは無関係なSOの答えには、このようなハッキングは含まれません... –

関連する問題