2017-01-01 5 views
3

私たちは1イベント、2加入者を持っています。イベントが発生すると、第1のサブジブラ(関数)変更パラメータがあり、このパラメータは参照型です。 2番目のサブスクライバは、変更されたパラメータまたは元のパラメータを取得しますか?代理人はデリゲートチェーンのパラメータを変更できますか? (C#)

+1

コード例を追加して、意味を示してもいいですか?私はあなたが答えたのは、変更されたパラメータを取得したということではないかと疑いますが、コード例では質問がより明確になります。 –

+1

ここではイベント特有のことは何もないことに注意してください。できるだけシンプルにするために、デリゲートだけで質問を語句にする方が良いかもしれません。 –

答えて

10

値が異なる値を持つようにパラメータを変更することはできませんが、(いつものように)値が参照するオブジェクトを変更できる可能性があります。

例:

using System; 
using System.Text; 

class Test 
{ 
    static void Main(string[] args) 
    { 
     Action<StringBuilder> action1 = sb => 
     { 
      Console.WriteLine(sb); 
      sb = new StringBuilder("x"); 
     }; 
     Action<StringBuilder> action2 = sb => 
     { 
      Console.WriteLine(sb); 
      sb.Append("y"); 
     }; 
     Action<StringBuilder> action3 = sb => 
     { 
      Console.WriteLine(sb); 
      sb.Append("z"); 
     }; 

     Action<StringBuilder> all = action1 + action2 + action3; 
     StringBuilder builder = new StringBuilder("a"); 
     all(builder); 
     Console.WriteLine(builder); 
    } 
} 

出力:すなわち

a 
a 
ay 
ayz 

  • 最初のアクションは、そのパラメータの値を変更します。これは、他に何も影響しません
  • 2番目のアクションは、そのパラメータが第二のアクションによって行われた変更を「見る」ことができる
  • 第三アクションを指しStringBuilderオブジェクトに「Y」を付加し、それが「Z」
  • を追加デリゲートが呼び出された後、それらの変更は、この値によってパラメータを渡す正規メソッド呼び出しなど、すべて全く同じである発信者

に見える

  • あります。

    今、あなたはrefパラメータを使用してデリゲートを宣言することができます - それはrefパラメータを持つメソッドのように動作し、その時点では、パラメータ自体への変更は、チェーンの後の代表者には見えです。ここでは新しいRefAction<T>デリゲートを使用して上記の例のバージョンがあります:

    using System; 
    using System.Text; 
    
    delegate void RefAction<T>(ref T arg); 
    
    class Test 
    { 
        static void Main(string[] args) 
        { 
         RefAction<StringBuilder> action1 = (ref StringBuilder sb) => 
         { 
          Console.WriteLine(sb); 
          sb = new StringBuilder("x"); 
         }; 
         RefAction<StringBuilder> action2 = (ref StringBuilder sb) => 
         { 
          Console.WriteLine(sb); 
          sb.Append("y"); 
         }; 
         RefAction<StringBuilder> action3 = (ref StringBuilder sb) => 
         { 
          Console.WriteLine(sb); 
          sb.Append("z"); 
         }; 
    
         RefAction<StringBuilder> all = action1 + action2 + action3; 
         StringBuilder builder = new StringBuilder("a"); 
         all(ref builder); 
         Console.WriteLine(builder); 
        } 
    } 
    

    今、出力は次のようになります。

    a 
    x 
    xy 
    xyz 
    

    ... action1sbの値への変更があることを示しているどこにでも見える。

  • 関連する問題