delegate event Lambda

来源:互联网 发布:c语言哪些是闰年 编辑:程序博客网 时间:2024/06/09 19:00

一:DELEGATE介绍
    public delegate string MyDelegate(bool a, bool b, bool c);
    sealed class MyDelegate : System.MulticastDelegate
    {
        public MyDelegate(object target, uint functionAddress);
        public string Invoke(bool a, bool b, bool c);
        public IAsyncResult BeginInvoke(bool a, bool b, bool c, AsyncCallback cb, object state);
        public string EndInvoke(IAsyncResult result);
    }

    public delegate string MyOtherDelegate(out bool a, ref bool b, int c);
    sealed class MyOtherDelegate : System.MulticastDelegate
    {
        public MyOtherDelegate (object target, uint functionAddress);
        public string Invoke(out bool a, ref bool b, int c);
        public IAsyncResult BeginInvoke(out bool a, ref bool b, int c, AsyncCallback cb, object state);
        public string EndInvoke(out bool a, ref bool b, IAsyncResult result);
    }

    // 定义委托delegate后,程序内部会产生如下函数
    public sealed class DelegateName : System.MulticastDelegate
    {
        public DelegateName (object target, uint functionAddress);
        public delegateReturnValue Invoke(allDelegateInputRefAndOutParams);
        public IAsyncResult BeginInvoke(allDelegateInputRefAndOutParams, AsyncCallback cb, object state);
        public delegateReturnValue EndInvoke(allDelegateRefAndOutParams, IAsyncResult result);
    }

    public delegate void MyDelegate(object obj, int x);
    public class MyDelegate : System.MulticastDelegate
    {
        public MyDelegate(Object target, IntPtr methodPtr);
        public void virtual Invoke(object obj, int x);   
        public virtual IAsyncResult BeginInvoke(object obj, int x, AsyncCallback callback, object o);
        public virtual void EndInvoke(IAsyncResult result);
    }

    public abstract class MulticastDelegate : Delegate
    {
        public sealed override Delegate[] GetInvocationList();
        public static bool operator ==(MulticastDelegate d1, MulticastDelegate d2);
        public static bool operator !=(MulticastDelegate d1, MulticastDelegate d2);
        private IntPtr _invocationCount;
        private object _invocationList;
    }

    public abstract class Delegate : ICloneable, ISerializable
    {
        public static Delegate Combine(params Delegate[] delegates);
        public static Delegate Combine(Delegate a, Delegate b);
        public static Delegate Remove(Delegate source, Delegate value);
        public static Delegate RemoveAll(Delegate source, Delegate value);

        public static bool operator ==(Delegate d1, Delegate d2);
        public static bool operator !=( Delegate d1, Delegate d2);

        public MethodInfo Method { get; }
        public object Target { get; }
    }

    // 定义一个委托,相应的存在上述四个函数
    public delegate int BinaryOp(int x, int y);

    public class SimpleMath
    {
        public int Add(int x, int y)
        { return x + y; }
        public static int Subtract(int x, int y)
        { return x - y; }
    }

    class Program
    {
        //异步读取是的参数
        public class paramState
        {
            int x;
            int y;
            public BinaryOp b;
            public paramState(int x, int y, BinaryOp b)
            {
                this.x = x;
                this.y = y;
                this.b = b;
            }
        }

        static void Main(string[] args)
        {

            SimpleMath m = new SimpleMath();
            BinaryOp b = new BinaryOp(m.Add);

            Console.WriteLine("10 + 10 is {0}", b(10, 10));//内部调Invoke
            Console.WriteLine("10 + 10 is {0}", b.Invoke(10, 10));


            IAsyncResult ar = b.BeginInvoke(10, 10, null, null);
            int c = b.EndInvoke(ar);

            ar = b.BeginInvoke(10, 10, new AsyncCallback(addfun), null);//直接调
            c = b.EndInvoke(ar);

            //封装传递参数
            paramState state = new paramState(10, 10, b);
            ar = state.b.BeginInvoke(10, 10, new AsyncCallback(addfun), state);

            Console.ReadLine();
        }

        private static void addfun(IAsyncResult ar)
        {
            try
            {
                paramState tempState = (paramState)ar.AsyncState;
                lock (tempState.b)
                {
                    int result = tempState.b.EndInvoke(ar);
                }
                //if (true)
                //{
                //    return;
                //}

                //lock (tempState.b)
                //{
                //    tempState.b.BeginInvoke(10, 10, new AsyncCallback(addfun), state);
                //}
            }
            catch (System.Exception ex)
            {
                return;
            }
        }
    }

二:多委托,一个委托邦定多个函数,然后依次执行

    public class Car
    {
        // Define the delegate types.
        public delegate void AboutToBlow(string msg);
        public delegate void Exploded(string msg);

        //myCar.explodedList = new Car.Exploded(CallWhenExploded);
        //myCar.Accelerate(10);
        //myCar.explodedList = new Car.Exploded(CallHereToo);
        //myCar.Accelerate(10);
        private AboutToBlow almostDeadList; //如果是公有的化,容易被重新赋值
        private Exploded explodedList;

        // Add member to the invocation list.
        public void OnAboutToBlow(AboutToBlow clientMethod)
        { almostDeadList += clientMethod; }

        public void OnExploded(Exploded clientMethod)
        { explodedList += clientMethod; }

        // Remove member from the invocation list.
        public void RemoveAboutToBlow(AboutToBlow clientMethod)
        { almostDeadList -= clientMethod; }

        public void RemoveExploded(Exploded clientMethod)
        { explodedList -= clientMethod; }

        public void Accelerate(int delta)
        {
            //CarExploded
            explodedList("Sorry, this car is dead...");
            //CarIsAlmostDoomed + CarAboutToBlow
            almostDeadList("Careful buddy!  Gonna blow!");
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("***** Delegates as event enablers *****/n");

            Car c1 = new Car("SlugBug", 100, 10);

            // 注册时间,类似函数地址邦定
            Car.Exploded d = new Car.Exploded(CarExploded);
            c1.OnAboutToBlow(new Car.AboutToBlow(CarIsAlmostDoomed));
            c1.OnAboutToBlow(new Car.AboutToBlow(CarAboutToBlow));
            c1.OnExploded(d);
            //c1.OnExploded(new Car.Exploded(CarExploded));
            Console.WriteLine("***** Speeding up *****");
            for (int i = 0; i < 6; i++)
                c1.Accelerate(20);

            c1.RemoveExploded(d);

            Console.ReadLine();
        }

        public static void CarAboutToBlow(string msg)
        { Console.WriteLine(msg); }

        public static void CarIsAlmostDoomed(string msg)
        { Console.WriteLine("Critical Message from Car: {0}", msg); }

        public static void CarExploded(string msg)
        { Console.WriteLine(msg); }
    }

三:使用委托创建对象过程中的继承问题
    public class Car
    {
        // Define the Delegate types.
        public delegate void AboutToBlow(string msg);
        public delegate void Exploded(string msg);
        public delegate void CarMaintenanceDelegate(Car c);

        //myCar.explodedList = new Car.Exploded(CallWhenExploded);
        //myCar.Accelerate(10);
        //myCar.explodedList = new Car.Exploded(CallHereToo);
        //myCar.Accelerate(10);
        private AboutToBlow almostDeadList; //如果是公有的化,容易被重新赋值
        private Exploded explodedList;

        // Add member to the invocation list.
        public void OnAboutToBlow(AboutToBlow clientMethod)
        { almostDeadList += clientMethod; }

        public void OnExploded(Exploded clientMethod)
        { explodedList += clientMethod; }

        // Remove member to the invocation list.
        public void RemoveAboutToBlow(AboutToBlow clientMethod)
        { almostDeadList -= clientMethod; }

        public void RemoveExploded(Exploded clientMethod)
        { explodedList -= clientMethod; }
    }
    class SportsCar : Car{}
    class Program
    {
        public delegate Car ObtainVehicalDelegate();//返回基类CAR

        public static Car GetBasicCar()
        { return new Car(); }

        public static SportsCar GetSportsCar()  //返回子类SportsCar
        { return new SportsCar(); }

        static void Main(string[] args)
        {
            Console.WriteLine("***** Delegate Covariance *****/n");
            ObtainVehicalDelegate targetA = new ObtainVehicalDelegate(GetBasicCar);
            Car c = targetA();
            Console.WriteLine("Obtained a {0}", c);

            // Covariance allows this target assignment.
            ObtainVehicalDelegate targetB = new ObtainVehicalDelegate(GetSportsCar);
            SportsCar sc = (SportsCar)targetB();    //需要强制转换
            Console.WriteLine("Obtained a {0}", sc);
            Console.ReadLine();
        }
    }

四:委托参数泛化,即通用化
    public delegate void MyGenericDelegate<T>(T arg);   //模板化
    public delegate void MyDelegate(object arg);        //使用基类模拟模板化

    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("***** Generic Delegates *****/n");

            MyGenericDelegate<string> strTarget = new MyGenericDelegate<string>(StringTarget);
            strTarget("Some string data");

            MyGenericDelegate<int> intTarget = new MyGenericDelegate<int>(IntTarget);
            intTarget(9);

            Console.WriteLine("/nNow not using generics!/n");
            MyDelegate d = new MyDelegate(MyTarget);
            d("More string data");

            MyDelegate d2 = MyTarget;
            d2(9);

            Console.ReadLine();
        }

        static void StringTarget(string arg)
        {
            Console.WriteLine("arg in uppercase is: {0}", arg.ToUpper());
        }
        static void IntTarget(int arg)
        {
            Console.WriteLine("++arg is: {0}", ++arg);
        }

        static void MyTarget(object arg)
        {
            if (arg is int)
            {
                int i = (int)arg;
                Console.WriteLine("++arg is: {0}", ++i);
            }
            if (arg is string)
            {
                string s = (string)arg;
                Console.WriteLine("arg in uppercase is: {0}", s.ToUpper());
            }
        }
    }

五:EVETN 和DELEGATE类似,他们都支持+=,-=,但是EVENT不支持=,而DELEGATE支持,区别如下
    delegate一般用作私有函数,作为公有时,容易被重新赋值
    myCar.explodedList = new Car.Exploded(CallWhenExploded);
    myCar.Accelerate(10);
    myCar.explodedList = new Car.Exploded(CallHereToo);
    myCar.Accelerate(10);
    但是EVENT则不会,
    c1.AboutToBlow = new Car.CarEventHandler(CarIsAlmostDoomed);//会报错


    public class Car
    {
        public delegate void CarEventHandler(string msg);
        public event CarEventHandler Exploded;  //公有,DELEGATE也可以改成公有,但是改成后,会被重新赋值,但是EVENT没有重载=,所以不会
        public event CarEventHandler AboutToBlow;//公有,DELEGATE也可以改成公有

        public void Accelerate(int delta)
        {

            if (Exploded != null)
                Exploded("Sorry, this car is dead...");

            if (AboutToBlow != null)
                AboutToBlow("Careful buddy!  Gonna blow!");
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("***** Fun with Events *****/n");

            Car c1 = new Car("SlugBug", 100, 10);

            c1.AboutToBlow += new Car.CarEventHandler(CarIsAlmostDoomed);
            c1.AboutToBlow += new Car.CarEventHandler(CarAboutToBlow);

            Car.CarEventHandler d = new Car.CarEventHandler(CarExploded);
            c1.Exploded += d;

            Console.WriteLine("***** Speeding up *****");
            for (int i = 0; i < 6; i++)
                c1.Accelerate(20);

            c1.Exploded -= d;

            Console.WriteLine("/n***** Speeding up *****");
            for (int i = 0; i < 6; i++)
                c1.Accelerate(20);

            Console.ReadLine();
        }

        public static void CarAboutToBlow(string msg)
        { Console.WriteLine(msg); }

        public static void CarIsAlmostDoomed(string msg)
        { Console.WriteLine("Critical Message from Car: {0}", msg); }

        public static void CarExploded(string msg)
        { Console.WriteLine(msg); }
    }

六:多参数事件CarEventHandler(object sender, CarEventArgs e);
    public class CarEventArgs : EventArgs
    {
        public readonly string msg;

        public CarEventArgs(string message)
        {
            msg = message;
        }
    }

    public class Car
    {
        public delegate void CarEventHandler(object sender, CarEventArgs e);

        public event CarEventHandler Exploded;
        public event CarEventHandler AboutToBlow;

        public void Accelerate(int delta)
        {
            if (Exploded != null)
                Exploded(this, new CarEventArgs("Sorry, this car is dead..."));

            if (AboutToBlow != null)
                AboutToBlow(this, new CarEventArgs("Careful buddy!  Gonna blow!"));
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("***** Prim and Proper Events *****/n");

            Car c1 = new Car("SlugBug", 100, 10);

            c1.AboutToBlow += new Car.CarEventHandler(CarIsAlmostDoomed);
            c1.AboutToBlow += new Car.CarEventHandler(CarAboutToBlow);

            Car.CarEventHandler d = new Car.CarEventHandler(CarExploded);
            c1.Exploded += d;

            Console.WriteLine("***** Speeding up *****");
            for (int i = 0; i < 6; i++)
                c1.Accelerate(20);

            c1.Exploded -= d;

            Console.WriteLine("/n***** Speeding up *****");
            for (int i = 0; i < 6; i++)
                c1.Accelerate(20);

            Console.ReadLine();
        }

        //主要区别在下面
        public static void CarAboutToBlow(object sender, CarEventArgs e)
        { Console.WriteLine("{0} says: {1}", sender, e.msg); }

        public static void CarIsAlmostDoomed(object sender, CarEventArgs e)
        {
            if (sender is Car)
            {
                Car c = (Car)sender;
                c.CrankTunes(false);
            }
            Console.WriteLine("Critical Message from {0}: {1}", sender, e.msg);
        }

        public static void CarExploded(object sender, CarEventArgs e)
        { Console.WriteLine("{0} says: {1}", sender, e.msg); }
    }

七:EVENT通用模板类型
    public class CarEventArgs : EventArgs
    {
        public readonly string msg;

        public CarEventArgs(string message)
        {
            msg = message;
        }
    }

    public class Car
    {
        //没有,也不需要DELEGATE声明
        public event EventHandler<CarEventArgs> Exploded;
        public event EventHandler<CarEventArgs> AboutToBlow;


        public void Accelerate(int delta)
        {

            if (Exploded != null)
                Exploded(this, new CarEventArgs("Sorry, this car is dead..."));
            if (AboutToBlow != null)
                AboutToBlow(this, new CarEventArgs("Careful buddy!  Gonna blow!"));
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("***** Prim and Proper Events *****/n");

            Car c1 = new Car("SlugBug", 100, 10);

            c1.AboutToBlow += new EventHandler<CarEventArgs>(CarIsAlmostDoomed);
            c1.AboutToBlow += new EventHandler<CarEventArgs>(CarAboutToBlow);

            //区别
            EventHandler<CarEventArgs> d = new EventHandler<CarEventArgs>(CarExploded);
            c1.Exploded += d;

            Console.WriteLine("***** Speeding up *****");
            for (int i = 0; i < 6; i++)
                c1.Accelerate(20);

            c1.Exploded -= d;

            Console.WriteLine("/n***** Speeding up *****");
            for (int i = 0; i < 6; i++)
                c1.Accelerate(20);

            Console.ReadLine();
        }

        public static void CarAboutToBlow(object sender, CarEventArgs e)
        { Console.WriteLine("{0} says: {1}", sender, e.msg); }

        public static void CarIsAlmostDoomed(object sender, CarEventArgs e)
        {
            if (sender is Car)
            {
                Car c = (Car)sender;
                c.CrankTunes(false);
            }
            Console.WriteLine("Critical Message from {0}: {1}", sender, e.msg);
        }

        public static void CarExploded(object sender, CarEventArgs e)
        { Console.WriteLine("{0} says: {1}", sender, e.msg); }
    }

八:匿名委托方式
    public class CarEventArgs : EventArgs
    {
        public readonly string msg;
        public CarEventArgs(string message)
        {
            msg = message;
        }
    }

    public class Car
    {
        public delegate void CarEventHandler(object sender, CarEventArgs e);

        public event CarEventHandler Exploded;
        public event CarEventHandler AboutToBlow;

        public void SpeedUp(int delta)
        {
            if (Exploded != null)
                Exploded(this, new CarEventArgs("Sorry, this car is dead..."));
            if (AboutToBlow != null)
                AboutToBlow(this, new CarEventArgs("Careful buddy!  Gonna blow!"));
        }
    }
    static void Main(string[] args)
    {
        Console.WriteLine("***** Anonymous Methods *****");

        int aboutToBlowCounter = 0;

        Car c1 = new Car("SlugBug", 100, 10);

        //匿名注册
        c1.AboutToBlow += delegate
        {
            aboutToBlowCounter++;//不可以接口OUT或则REF修饰的变量
            Console.WriteLine("Eek!  Going too fast!");
        };

        c1.AboutToBlow += delegate(object sender, CarEventArgs e)
        {
            aboutToBlowCounter++;
            Console.WriteLine("Message from Car: {0}", e.msg);
        };

        c1.Exploded += delegate(object sender, CarEventArgs e)
        { Console.WriteLine("Message from Car: {0}", e.msg); };

        Console.WriteLine("/n***** Speeding up *****");
        for (int i = 0; i < 6; i++)
            c1.SpeedUp(20);

        Console.WriteLine("AboutToBlow event was fired {0} times", aboutToBlowCounter);

        Console.ReadLine();
    }

九:GROUP转换
    public class SimpleMath
    {
        public delegate void MathMessage(string msg);
        public event MathMessage ComputationFinished;

        public int Add(int x, int y)
        {
            ComputationFinished("Adding complete.");
            return x + y;
        }

        public int Subtract(int x, int y)
        {
            ComputationFinished("Subtracting complete.");
            return x - y;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("***** Method Conversion *****");

            SimpleMath m = new SimpleMath();
            //m.ComputationFinished += new SimpleMath.MathMessage(ComputationFinishedHandler);
            m.ComputationFinished += ComputationFinishedHandler;
            Console.WriteLine("10 + 10 is {0}", m.Add(10, 10));

            SimpleMath.MathMessage mmDelegate = (SimpleMath.MathMessage)ComputationFinishedHandler;
            Console.WriteLine(mmDelegate.Method);
            Console.ReadLine();
        }
        //参数和返回值如果不一致,就会报错
        static void ComputationFinishedHandler(string msg)
        {
            Console.WriteLine(msg);
        }
    }

    //delegate也类似
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("***** Delegates as event enablers *****/n");

            Car c1 = new Car("SlugBug", 100, 10);
      
            Car.Exploded d = new Car.Exploded(CarExploded);

            //c1.almostDeadList += new Car.AboutToBlow(CarIsAlmostDoomed);
            //c1.almostDeadList += new Car.AboutToBlow(CarAboutToBlow);
            c1.almostDeadList += CarIsAlmostDoomed;
            c1.almostDeadList += CarAboutToBlow;
            c1.explodedList += d;

            Console.WriteLine("***** Speeding up *****");
            for (int i = 0; i < 6; i++)
                c1.Accelerate(20);
            c1.explodedList -= d;

            Console.ReadLine();
        }

        public static void CarAboutToBlow(string msg)
        { Console.WriteLine(msg); }

        public static void CarIsAlmostDoomed(string msg)
        { Console.WriteLine("Critical Message from Car: {0}", msg); }

        public static void CarExploded(string msg)
        { Console.WriteLine(msg); }
    }

十:Lambda Expression
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("***** Fun with Lambdas *****/n");

            TraditionalDelegateSyntax();
            AnonymousMethodSyntax();

            Console.WriteLine();
            LambdaExpressionSyntax();

            Console.ReadLine();
        }

        static void TraditionalDelegateSyntax()
        {
            List<int> list = new List<int>();
            list.AddRange(new int[] { 20, 1, 4, 8, 9, 44 });

            Predicate<int> callback = new Predicate<int>(IsEvenNumber);
            List<int> evenNumbers = list.FindAll(callback);

            Console.WriteLine("Here are your even numbers:");
            foreach (int evenNumber in evenNumbers)
            {
                Console.Write("{0}/t", evenNumber);
            }
            Console.WriteLine();
        }
        static bool IsEvenNumber(int i)
        {
            return (i % 2) == 0;
        }
        static void AnonymousMethodSyntax()
        {
            List<int> list = new List<int>();
            list.AddRange(new int[] { 20, 1, 4, 8, 9, 44 });

            List<int> evenNumbers = list.FindAll(delegate(int i)
            { return (i % 2) == 0; });

            Console.WriteLine("Here are your even numbers:");
            foreach (int evenNumber in evenNumbers)
            {
                Console.Write("{0}/t", evenNumber);
            }
            Console.WriteLine();
        }
        static void LambdaExpressionSyntax()
        {
            List<int> list = new List<int>();
            list.AddRange(new int[] { 20, 1, 4, 8, 9, 44 });

            //List<int> evenNumbers = list.FindAll((i) =>
            //{
            //    Console.WriteLine("value of i is currently: {0}", i);
            //    return ((i % 2) == 0);
            //});
            List<int> evenNumbers = list.FindAll(i => (i % 2) == 0);

            Console.WriteLine("Here are your even numbers:");
            foreach (int evenNumber in evenNumbers)
            {
                Console.Write("{0}/t", evenNumber);
            }
            Console.WriteLine();
        }
    }

十二:Lambda Expression另一例
    public class Car
    {
        // Define the Delegate types.
        public delegate void AboutToBlow(string msg);
        public delegate void Exploded(string msg);

        private AboutToBlow almostDeadList;
        private Exploded explodedList;

        public void OnAboutToBlow(AboutToBlow clientMethod)
        { almostDeadList += clientMethod; }

        public void OnExploded(Exploded clientMethod)
        { explodedList += clientMethod; }

        public void RemoveAboutToBlow(AboutToBlow clientMethod)
        { almostDeadList -= clientMethod; }

        public void RemoveExploded(Exploded clientMethod)
        { explodedList -= clientMethod; }

        public void SpeedUp(int delta)
        {
            if (explodedList != null)
                explodedList("Sorry, this car is dead...");
            if (almostDeadList != null)
                almostDeadList("Careful buddy!  Gonna blow!");
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("***** More Fun with Lambdas *****/n");
            Car c1 = new Car("SlugBug", 100, 10);

            c1.OnAboutToBlow(new Car.AboutToBlow(CarAboutToBlow));
            c1.OnExploded(new Car.Exploded(CarExploded));
            for (int i = 0; i < 6; i++)
                c1.SpeedUp(20);
            Console.ReadLine();

            c1.OnAboutToBlow(delegate(string msg) { Console.WriteLine(msg); });
            c1.OnExploded(delegate(string msg) { Console.WriteLine(msg); });
            for (int i = 0; i < 6; i++)
                c1.SpeedUp(20);
            Console.ReadLine();

            c1.OnAboutToBlow(msg => { Console.WriteLine(msg); });
            c1.OnExploded(msg => { Console.WriteLine(msg); });
            for (int i = 0; i < 6; i++)
                c1.SpeedUp(20);
            Console.ReadLine();
        }

        public static void CarAboutToBlow(string msg)
        { Console.WriteLine(msg); }

        public static void CarExploded(string msg)
        { Console.WriteLine(msg); }
    }