• <menu id="uku4c"><u id="uku4c"></u></menu>
  • <input id="uku4c"><u id="uku4c"></u></input>
  • <menu id="uku4c"></menu><menu id="uku4c"><acronym id="uku4c"></acronym></menu>
  • <menu id="uku4c"><tt id="uku4c"></tt></menu>
  • <menu id="uku4c"></menu>
  • <nav id="uku4c"><tt id="uku4c"></tt></nav>
  • C# 委托补充01

    上一篇文章写了委托的最基本的一些东西,本篇咱们扯扯委托其他的东西。

    示例1插件编程

    根据对委托的理解,委托可以把一个方法当作参数进行传递,利用这个特性我们可以使用委托,实现插件编程。

    public delegate int Transformer(int x);
    
    class Util{
        pubilc static void Transform(int[] values, Transformer t){
            for(int i = 0; i < values.Length; i++){
                values[i] = t?.Invke(values[i]);
            }
        }
    }
    
    class Test{
        static void Main(){
            int[] values = {1,2,3};
            Util.Transform(values, Sqare);
            
            foreach(int i in values){
                Console.WriteLine(i + " "); //1 4 9
            }
        }
        
        static int Sqare (int x) => x * x;
    }

    这里的Transform方法就是插件方法,它接受一个委托参数。

    示例2多播委托

    所有的委托都有多播的能力。这就意味着一个委托可以引用一个方法,或者引用一个组方法。委托使用 += 和 -=运算符联结多个委托实例。

    public class People{}
    public class Student:People{}
    public delegate void Action();
    
    class Program
    {
        static void Say(){
            Console.WriteLine("Say HI");
        }
        static void Write(){
            Console.WriteLine("Write Anything");
        }
        
        Action action = Say;
        action += Write;//action = action + Write;
        action();
        
        /*
            Say HI
            Write Anything
        */
        
        
        
    }

    委托会按照添加的顺序依次触发。如果存在返回值,那么调用者会将最后一个带有非void返回值类型的方法返回值进行返回,其他的返回值将会抛弃。

    - 和-= 运算符会从左侧委托操作数中将右侧的委托操作删除。
    对于为值为null的委托执行 + 或者+= 操作,等价于为委托指定一个新的值。同样在当委托只有一个目标方法时,执行-=操作等价于为委托指定null值。
    由于委托是一个类,所以委托是不可变,每次执行 += 或者-= 实质上等价于从新创建一个新的委托实例,并为它赋值。
    具体使用,比如说我们要建一栋大楼,需要很长一段时间,但是公司有要求每建好一层需要给公司汇报一下。

    public delegate void ProgressReporter(int floor);
    
    public class Edifice{
        public static void Build(ProgressReporter p){
            for(int i = 0; i < 18; i++){
                p(i);
                
                System.Threading.Thread.Sleep(1000);//添加点时间
            }
        }
    }
    class Test{
        static void Main(){
            ProgressReporter p = WriteProgressToConsole;
            p += AdviseToCompany;
            Edifice.Build(p);
        }
        
        static void WriteProgressToConsole(int fool) => Console.WriteLine($"{fool}层已建成");
        
        static void AdviseToCompany(int fool) => Console.WriteLine($"**项目,已经建好{fool}层。");
        
        
    }

    示例3泛型委托

    委托类型可以包含泛型类型参数,如:

    public delegate T Transformer<T> (T t);

    通过一个泛型参数,我们可以定义一个通用的Transformer,让它对任何类型都有效:

    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]);
            }
        }
    }
    class Test{
        static void Main(){
            int[] values = {1,2,3};
            Util.Transformer(values, Square);
            
            foreach(int i in values){
                Console.Write(i + " "); //1 4 9
            }
        }
        
        static int Sqare (int x) => x * x;
        
    }

    既然委托支持泛型参数,那么就可以定义一些小型的委托类型,它们可以具有任意的返回类型和合理的数目的参数,类如系统定义好的Action委托和Func委托(out和in标记可变性修饰符,在逆变和协变中有解释)。

    delegate void Action();
    delegate void Action<in T> (T arg);
    delegate void Action<in T1, in T2> (T1 arg1, T2 arg2)
    ………
    delegate TResule Func(out TResule)();
    delegate TResule Func<in T, out TResule> (T arg);
    delegate TResule Func<in T1, in T2, out TResule> (T1 arg1, T2 arg2)
    ………

    其中Action和Func 都可以支持16个参数。
    上面的Transform重写.

    public static void Transform<T> (T[] values, Func<T, T> transformer){
        for(int i = 0; i < values.Length; i++){
            values[i] = transformer(values[i]);
        }
    }

    委托还有很多东西,下次聊!

    参考自C#7.0核心技术指南

    相关文章
    相关标签/搜索
    每日一句
      每一个你不满意的现在,都有一个你没有努力的曾经。
    公众号推荐
       一个历史类的公众号,欢迎关注
    一两拨千金
    天下彩天空彩票与香港小说 开原市| 光山县| 江都市| 高邑县| 资中县| 武定县| 依兰县| 福建省| 尤溪县| 泰兴市| 台东县| 蒲江县| 虎林市| 长治县| 普宁市| 专栏| 绥阳县| 滁州市| 郑州市| 潼南县| 阿拉善盟| 沙坪坝区| 玛纳斯县| 天气| 隆回县| 武鸣县| 政和县| 清原| 长宁县| 乌恰县| 琼中| 阿鲁科尔沁旗| 延川县| 兴化市| 黎川县| 五华县| 昂仁县| http://fa.hz0j1r1vo.fun http://fa.hz0j2r5vo.fun http://fa.hz0j1r7vo.fun http://fa.hz0j0r8vo.fun http://fa.hz0j1r5vo.fun