2012-03-02 3 views
0

私は、「常に」ステップA、C、Dをその順序で実行するアルゴリズムを持っています。VB.NET - フックのメカニズム、またはメソッドのリストを実行する方法?

私はA、B、C、Dを実行する方法を許可したいと思います.Bは複数の方法があります。 C、Dは「影響を受けてはいけませんが、並列化できません。それは単にファイルに書いているだけです。

どのようにしても、私はデリゲートについて少し知っていて、AddressOfを使ってイベントハンドラをフックしています。

私は単純に "アドレス"または代理人ではないものの配列またはコレクションを作成することを考えていました。

これも可能ですか?

これは「最適な」方法ですか?私はオブジェクトで動作を強制する方法を知っていますが、VB、.NETに既に組み込まれているメカニズムを再利用したいと考えています。

デーン

答えて

1

単純にイベントを使用して、複数のメソッドを格納して呼び出すことができます。イベントは基本的に合理化されたマルチキャストデリゲートなので、Delegate.Combineを使用する必要はありません。欠点は、メソッドが戻り値の型を持つことができないことです。

マルチキャストデリゲートを使用する別の方法もあります。この例では、メソッドから値を返すことを前提としています。これを必要としない場合は、メソッドをループする必要はありません。 myMethods.Invokeを使用することができます。上記その呼び出しコードの別の代替として、

'the methods will be stored here 
Private _MyMethods As [Delegate] 

'this is here to show the signature of the methods 
Public Delegate Function MyMethod(ByVal input As String) As String 

Public Sub AddMethod(ByVal method As MyMethod) 
    _MyMethods = [Delegate].Combine(_MyMethods, method) 
End Sub 

Public Sub RemoveMethod(ByVal method As MyMethod) 
    _MyMethods = [Delegate].Remove(_MyMethods, method) 
End Sub 

Public Sub InvokeMethods(ByVal input As String) 
    If _MyMethods Is Nothing Then Return 

    Dim myMethods As MyMethod = DirectCast(_MyMethods, MyMethod) 

    'since you'll want the return value of each methods, loop through the methods 
    For Each method As MyMethod In myMethods.GetInvocationList() 
     Dim value As String = method.Invoke(input) 

     'TODO: something with the value 
    Next 
End Sub 

、あなたはデリゲートをキャストする必要がないようにDelegate.DynamicInvokeメソッドを使用することができます。しかし、これはレイトバインディングを使用し、関数の場合は、戻り値をキャストする必要があります。

+0

Gideon EngelberthとTimiz0rの両方から学んだが、どちらかを選択しなければならなかった。ありがとうございます。 – Danedo

1

それはあなたが頻繁に見ものではないのですが、呼び出されたときに、単一のデリゲート変数が複数の機能を呼び出すように、あなたは、デリゲートを組み合わせることができます。

Dim midAction As Action(Of String) = AddressOf Console.WriteLine 
Dim m1 As New IO.StreamWriter(New IO.MemoryStream()) 
m1.AutoFlush = True 
Dim m2 As New IO.StreamWriter(New IO.MemoryStream()) 
midAction = CType([Delegate].Combine(New Action(Of String)(AddressOf Console.WriteLine), 
            New Action(Of String)(AddressOf m1.WriteLine), 
            New Action(Of String)(Sub(s) 
                  m2.WriteLine(s) 
                  m2.Flush() 
                  End Sub)), 
        Action(Of String)) 
midAction("test") 

ここで最大の低下は、タイプレスのDelegate.Combineがすべてのキャスティングを必要とすることです。

代理人のIEnumerableも働きます。は、複数の機能を呼び出すためにが必要です。

あなたの説明から、引数のセマンティクスに適しているように私は1つのデリゲートパラメータに固執すると思います。呼び出し元は、途中で呼び出す必要がある複数の関数がある場合に結合を実行できます。