zoukankan      html  css  js  c++  java
  • 协变和逆变随笔

    当使用委托时,一般会出现两种角色:广播者(broadcaster)和订阅者(subscriber)。
    广播者是包含委托字段的类型,它通过调用委托决定何时进行广播。
    而订阅者是方法的目标接收者。订阅者通过在广播者的委托上调用+=和-=来决定何时开始监听而何时监听结束。订阅者不知道也不会干涉其他的订阅者。
    而事件就是正式定义这一模式的语言功能。事件是一种使用有限的委托功能实现广播者/订阅者模型的结构。使用事件的主要目的在于保证订阅者之间不互相影响。

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace DelegateDemo
    {
        class Program
        {
            public delegate void ProgressReporter(int percentComplete);
            static void Main(string[] args)
            {
                {
                    //X x = new X();
                    //ProgressReporter p = x.InstanceProcess;
                    //p(99);
                    //Console.WriteLine(p.Target == x);
                    //Console.WriteLine(p.Method);
    
                    //ProgressReporter pt = StaticProcess;
                    //pt(100);
                    //Console.WriteLine(pt.Target);
                    //Console.WriteLine(pt.Method);
                }
                {
                    //int[] values = { 1, 2, 3 };
                    //Util.Transform(values, Square);
                    //foreach (var item in values)
                    //{
                    //    Console.Write(item + " ");
                    //}
                }
                {
                    //适用于引用类型的接口
                    //逆变 协变   逆变可以参考一个词语逆子,故逆变是子=>基, 协变是基 => 子(更具体的类型)
                    //协变 用关键字 out 输出  就是可以输出子类   
                    //逆变 用关键字 in 输入  就是输入参数可以是基类
                    //例子 interface ITestOut<out T>{ T Method();}
                    //例子 interface ITestIn<in <T>{ void Method(T obj);}
                    //事件  事件是一种使用有限的委托功能实现广播着/订阅者模型的结构,使用事件的主要目的在于保证订阅者之间不互相影响
                    //int[] collection = { 4, 5, 6 };
                    //UtilForItrans.TransformAll(collection, new Squarer());
                    //foreach (var item in collection)
                    //{
                    //    Console.Write(item + " ");
                    //}
                }
                {
                    //StringAction sa = new StringAction(ActOnObject);
                    //sa("hello");
                    //ObjectRetriever or = new ObjectRetriever(RetrieveString);
                    //Console.WriteLine(or());
                }
                Console.Read();
    
            }
            delegate object ObjectRetriever();
            delegate void StringAction(string s);
            private static void ActOnObject(object o) => Console.WriteLine(o);
            private static int Square(int arg) => arg * arg;
            static string RetrieveString() => "Hello";
            static void StaticProcess(int percentComplete)
            {
                Console.WriteLine(percentComplete);
            }
        }
    
        class X
        {
            public void InstanceProcess(int percentComplete)
            {
                Console.WriteLine(percentComplete);
            }
        }
        public delegate T Transformer<T>(T arg);
        public class Util
        {
            public static void Transform<T>(T[] values,Transformer<T> t)
            {
                for (int i = 0; i < values.Length; i++)
                {
                    values[i] = t(values[i]);
                }
            }
        }
    
        public interface ITransformer
        {
            int Transform(int x);
        }
    
        public class UtilForItrans
        {
            public static void TransformAll(int[] values,ITransformer t)
            {
                for(int i = 0; i < values.Length; i++)
                {
                    values[i] = t.Transform(values[i]);
                }
            }
        }
    
        class Squarer : ITransformer
        {
            public int Transform(int x) => x * x;
        }
    
        class Broadcaster
        {
             PriceChangedHandler priceChanged;
            public event PriceChangedHandler PriceChanged {
                add { priceChanged += value; }
                remove { priceChanged -= value; }
            }
        }
        public delegate void PriceChangedHandler(decimal oldPrice, decimal newPrice);
    
        //如果去掉event,不会影响运行结果,但是影响如下:
        //通过重新指派PriceChanged替换其他的订阅者(不用+=运算符)
        //清楚所有的订阅者(将PriceChanged设置位null)
        //通过调用其委托广播到其他的订阅者
        public class Stock
        {
            string symbol;
            decimal price;
            public Stock(string symbol)
            {
                this.symbol = symbol;
            }
    
            public event PriceChangedHandler PriceChanged;
    
            public decimal Price {
                get {
                    return price;
                }
                set {
                    if (price == value) return;
                    decimal oldPrice = price;
                    price = value;
                    if(PriceChanged != null)
                    {
                        PriceChanged(oldPrice, price);
                    }
                }
            }
    
        }
    }
  • 相关阅读:
    POJ 1469 COURSES 二分图最大匹配
    POJ 1325 Machine Schedule 二分图最大匹配
    USACO Humble Numbers DP?
    SGU 194 Reactor Cooling 带容量上下限制的网络流
    POJ 3084 Panic Room 求最小割
    ZOJ 2587 Unique Attack 判断最小割是否唯一
    Poj 1815 Friendship 枚举+求最小割
    POJ 3308 Paratroopers 最小点权覆盖 求最小割
    1227. Rally Championship
    Etaoin Shrdlu
  • 原文地址:https://www.cnblogs.com/morec/p/11904268.html
Copyright © 2011-2022 走看看