C#における依頼概念


依頼(delegate)変数を定義するために使用できるデータ型と見なすこともできます.しかし、特殊なデータ型であり、定義された変数が受信できる数値は1つの関数にすぎません.より正確には、依頼型の変数は1つの関数のアドレスを受信することができ、C++言語の関数ポインタに似ています.簡単に言えば、依頼変数は1つの関数と見なすことができます.タイプの安全な関数ポインタで、その要求に合致する関数アドレスしか受信できません.次の例を示します.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            MathOptDelegate oppDel;
            MathOpt obj = new MathOpt();
            //               ,             
            oppDel = obj.Add;
            Console.WriteLine(oppDel(1,2));
        }
    }
    public class MathOpt
    {
        public int Add(int arg1,int arg2) 
        {
            return arg1 + arg2;
        }
    }
    //      MathOptDelegate,     delegate
    public delegate int MathOptDelegate(int value1,int value2);
}

委任はDelegateから派生したクラスであり,受信関数を委任する場合,関数パラメータタイプと戻り値は委任定義と同じであることが要求される.この要件を満たす限り,静的でもインスタンスでも委任できる.
実際には、委任は関数を表すだけでなく、「スタック」関数を組み合わせて一括して実行することもできます.次の例を示します.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {
            MyDelegate a, b, c, d;

            //    Hello       a
            a =MyClass.Hello;
            Console.WriteLine("      a:");
            a("a");

            //     Goodbye         b:
            b = MyClass.Goodbye;
            Console.WriteLine("      b:");
            b("b");

            // a   b        c,
            c = a + b;
            Console.WriteLine("      c:");
            c("c=a+b");// c           

            //      c    a ,   b, d      ,
            d = c - a;
            Console.WriteLine("      d:");
            d("d=c-a");//    Goodbye   :
        }
    }
    delegate void MyDelegate(String s);
    class MyClass
    {
        public static void Hello(String s)
        {
            Console.WriteLine("  ,{0}",s);
        }
        public static void Goodbye(String s)
        {
            Console.WriteLine("  ,{0}", s);
        }
    }
}