ホームページ  >  記事  >  バックエンド開発  >  C# の委任と匿名委任の詳細な紹介

C# の委任と匿名委任の詳細な紹介

黄舟
黄舟オリジナル
2017-09-02 14:53:541560ブラウズ

この記事では主に C# デリゲーションと匿名デリゲーションの関連情報を詳しく紹介します。興味のある方は参考にしてください。ライフ』ですが、コミッショニング部分だけで書いている内容が多いので、ラムダ式に関する内容は分けて後ほど書きます。

ラムダ式を誰が発明したのかは知りませんが、私がラムダ式に初めて触れたのは VS2008 を使用していたときだったということだけを覚えているので、まず Microsoft によって発明されたと考えてみましょう。

ラムダ式に出会って以来、ラムダ式はますます人気が高まっており、現在は Java 8 でサポートされており、kotlin は C# と F# を広範囲にコピーしています (かつては C# も Java を同じように扱っていませんでした)。 。実際、これはラムダ式の重要性を十分に示しています。 Lambda を理解するには、まず委任について理解する必要があります。

委任:

今、2 つの整数を処理するプログラムを開発したいとします (加算演算が最初に処理されると仮定します)

public class Worker
    {
      /// <summary>
      /// 处理两个数
      /// </summary>
      /// <param name="a"></param>
      /// <param name="b"></param>
      /// <returns></returns>
      public int HandleTwoNumber(int a,int b)
      {
        return a + b;
      }
    }
static void Main(string[] args)
    {
      int a = int.Parse(Console.ReadLine());
      int b = int.Parse(Console.ReadLine());

      Worker worker = new Worker();
      int result = worker.HandleTwoNumber(a, b);
      Console.WriteLine(String.Format("Result:{0}", result));

      string p = Console.ReadLine();
}

しばらく経って、減算演算に変更する必要がある場合:

public class Worker
    {
      public int HandleTwoNumber(int a,int b)
      {
        return a - b;
      }
    }

a+b から a-b への変化は非常に小さいですが、ここでは複数の変化がある可能性があります (引き算から割り算まで...)。変更がある場合、その変更をカプセル化する必要があります。ここでは、a と b の動作を抽象化する必要があります。デリゲート

public class Worker
    {
      public delegate int TwoNumberHandleMethodDelegate(int x, int y);
      public int HandleTwoNumber(int a,int b)
      {
        return a + b;
      }
    }

public delegate int TwoNumberHandleMethodDelegate(int x, int y); ここでデリゲートという注釈が付けられているのは、これがデリゲート定義であることを示します。デリゲートを削除して定義を見ると、これがメソッド本体のない抽象メソッドであることがわかります。したがって、委任の意味は、抽象メソッドと同じ署名形式を持つメソッドのタイプです。デリゲートは、ユーザーが定義する新しいデータ型であり、int や class と同じデータ型です。 int は整数を表し、int 型変数には任意の整数を代入できます。TwoNumberHandleMethodDelegate は 2 つの int 型パラメータを受け取り、int 型の結果を返すメソッドを表します。したがって、上記の要件を満たすメソッドを変数に代入できます。 TwoNumberHandleMethodDelegate 型の。

このようにして、Worker コードは次のように変更できます:


public class Worker
    {
      public delegate int TwoNumberHandleMethodDelegate(int x, int y);
      public int HandleTwoNumber(int a, int b, TwoNumberHandleMethodDelegate handle)
      {
        return handle(a, b);
      }
    }

この方法で、a と b の操作はカプセル化され、すべての変更は呼び出し元によって処理されます。ここでの意味: HandleTwoNumber は 2 つの整数 a と b を処理します。具体的な処理は handle によって実装されます。この時点で、このメソッドをどのように呼び出すのかと疑問に思うかもしれません。呼び出しは次のとおりです:

private static int Add(int a, int b)
    {
      return a + b;
    }

    private static int Sub(int a, int b)
    {
      return a - b;
    }

    static void Main(string[] args)
    {
      int a = int.Parse(Console.ReadLine());
      int b = int.Parse(Console.ReadLine());
      Worker.TwoNumberHandleMethodDelegate method = new Worker.TwoNumberHandleMethodDelegate(Add);
      Worker worker = new Worker();
      int result = worker.HandleTwoNumber(10, 10,method);
       //int result = worker.HandleTwoNumber(10, 10, Sub);//简化版
      Console.WriteLine(String.Format("Result:{0}", result));
 }

上記のプログラムによれば、Main コード ブロックがワーカーの呼び出し元です。呼び出し元として、ワーカーに実行してもらいたい作業を最もよく知っている必要があります。したがって、呼び出し先のワーカーとしては、呼び出し元 Main によって指定された ab パラメーターを受け取り、Main によってカスタマイズされたアルゴリズム メソッドを実行し、アルゴリズムに従ってアルゴリズムを実行して結果を返すだけで済みます。上記のコードは単純ですが、その意味は多岐にわたり、プログラミングの時間が増えるにつれて理解が深まると思います。

デリゲート変数に値を割り当てる標準的な方法に加えて、次のように簡略化することもできます。

Worker.TwoNumberHandleMethodDelegate method = new Worker.TwoNumberHandleMethodDelegate(Add);
      Worker worker = new Worker();
      int result = worker.HandleTwoNumber(10, 10,method);
//可简化为
// int result = worker.HandleTwoNumber(10, 10,Add);

コンパイラは、Add が TwoNumberHandleMethodDelegate の定義に準拠しているかどうかを自動的にチェックし、準拠している場合は、デリゲート変数に直接割り当てられるメソッド名。

匿名デリゲート

上記のコード例を通して、TwoNumberHandleMethodDelegate メソッド変数に値 Add(Sub) が割り当てられていることが簡単にわかります。そのため、method(...) を呼び出すときは、Add(..) を呼び出すことと同じです。 ...) 。このように

メソッドとAddは全く同等であると考えられますので、Addの定義内容をメソッド変数に直接代入することはできるのでしょうか?答えは「はい」です:

static void Main(string[] args)
    {

      Worker.TwoNumberHandleMethodDelegate method =private static int Add(int a, int b)
    {
      return a + b;
    };
}

しかし、上記のように機械的に適用することは不可能であり、依然として変更を加える必要があります。変更点は次のとおりです。現在のコードは Main メソッド内にあるため、アクセス修飾子が削除され、同時に static も削除される必要があります。コンパイラは、メソッドに値を割り当てようとしていることを認識するため、その値を割り当てられるメソッドは int の戻り値の型を満たす必要があるため、割り当て後のメソッドは Add と同等であり、後続の呼び出しはメソッド変数を通じて完了でき、すべての Add メソッド名は必要ないため、現時点ではすべての Int を削除する必要はありません。削除されます。したがって、コードは次の形式に変更されます:

static void Main(string[] args)
    {

      Worker.TwoNumberHandleMethodDelegate method =  (int a, int b)
    {
      return a + b;
    };
}

上記の変更後、内容は大幅に簡略化されましたが、メソッド割り当ての = の右端は何ですか?現時点では、コンパイラはこれがメソッドであることを正しく識別できません。これは、メソッドの定義にアクセス修飾子、戻り値の型、メソッド名、パラメータ リスト、メソッド本体を含める必要があるためです。これが簡略化されたメソッドであることは心の中ではわかっていても、コンパイラはあなたの心を理解しません...、以下が簡略化されたメソッドであることをコンパイラに伝える限り、それは問題ではありません。

static void Main(string[] args)
    {

      Worker.TwoNumberHandleMethodDelegate method =  delegate(int a, int b)
    {
      return a + b;
    };
}

ご想像のとおり、コンパイラは右側が単純化されたメソッドであることを認識しました。これで、通常どおりに割り当てて使用できます。

上記の定義から、デリゲートでマークされた簡易メソッドには、Add/Sub のような固定の名前がないことがわかります。したがって、このメソッドを匿名委任と呼びます (私はこれを匿名メソッドと呼ぶことに慣れています)。

また、匿名デリゲートが定義された後は、Main コード ブロック内のローカル変数メソッドに割り当てられるため、メソッドのスコープを超えるとメソッドが呼び出されないことにも注意してください。これにより、匿名メソッド、匿名デリゲート、および匿名関数が最も一般的に使用され、一度だけ使用する必要がある関数コードを定義することになります。

以上がC# の委任と匿名委任の詳細な紹介の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。