zoukankan      html  css  js  c++  java
  • C#委托

    • 委托定义:
      • 委托是一个引用类型,表示对具体特定参数列表和返回类型的方法的引用,在实例化委托时,可以其实例与任何具有兼容签名和返回类型的方法相关联;
        
      • 是安全封装方法的类型,类似于C和C++中的函数指针。这是来自微软官方的定义。再来看一下国内一些网站的定义:委托是一个类,它定义了方法的类型,
        
      • 使得可以将方法当作另一个方法的参数来进行传递,这种将方法动态地赋给参数的做法,可以避免在程序中大量使用if-else/switch 语句,同时使得程序
        
      • 具有更好的可扩展性。通过上面的定义一些基础不好的同学是不是,仍然不知道是用来干嘛,先别急咱们一点一点的来聊。    
        
      • 首先 通过定义咱们知道了一个很重要的信息:委托是一个类型、是类。既然委托是一个类,那么委托是不是也应该具有类的特性。
      • 咱们来看一下定义一个委托的方法:delegagte void Evenhandler();
      • 看到是不是有些小伙伴会问,“委托不是一个类吗?为什么在定义的时候这么一句就完了呢?”
        
      • 咱们来看一个实例,通过反编译工具咱们看一下,委托通过编译之后长什么样子
        

    在图中咱们是不是可以清楚的看到,委托真的是一个类,继承自System.Object;并且它还有自己的方法:Invoke();BeginInvoke();EndInvoke();
    那么怎么使用委托呢?看下面的例子:
    public delegate void ShowResult(int a,int b);
    static void Main(string[] args)
    {
    ShowResult showResult = Add;
    //ShowResult showResult = New ShowResult(Add);
    DelegateTest.Calculate(showResult , 5, 6);

            Console.Read();
        }
    
        public static void Add(int a, int b) {
            Console.WriteLine(a + b);
        }
    
        public static void Divide(int a, int b) {
            Console.WriteLine(a / b);
        }
        public static void Subtract(int a, int b) {
            Console.WriteLine(a - b);
        }
        public static void Multiply(int a, int b) {
            Console.WriteLine(a * b);
        }
    

    看了上面的例子是不是感觉委托没有什么用,我么直接调用相应的方法不就行了吗?为什么还要绕个远路呢?
    我们来看一下上面的实例,实例的目的是输出两个数的加、减、乘、除,这四个方法目前有一个共性的操作就是需要计算的结果进行输出。这仅仅是目前的需求,但是为了不挖坑,对传进去的参数是不是需要检测。
    现在针对现在的程序添加一些规则:1:a、b都要是正整数;2:对每次操作都要写入日志。
    考虑一下,添加这些规则,咱们是不是需要怎么修改代码。
    public delegate int ShowResult(int a,int b);

        static void Main(string[] args)
        {
            ShowResult showResult = Add;
            //ShowResult showResult = New ShowResult(Add);
            DelegateTest.Calculate(showResult , 5, 6);
            Console.Read();
        }
        
        
        public static int Add(int a, int b) {
            return a + b;
        }
        public static int Divide(int a, int b) {
            return a / b;
        }
        public static int Subtract(int a, int b) {
            return a - b;
        }
        public static int Multiply(int a, int b) {
            return a * b;
        }
    
        public static void Calculate(ShowResult showResult, int a, int b) {
            if(a < 0 || b < 0){
                Console.WriteLine("参数有误");
            }else{     
                System.Reflection.MethodInfo methodInfo = RuntimeReflectionExtensions.GetMethodInfo(showResult);
                Console.WriteLine("在这里写入一条日志" + methodInfo.ToString());
                Console.WriteLine(showResult(a, b));
                //Console.WriteLine(showResult?.Invoke(a, b)); ?.  null检查 C#6.0以上版本
            }
        }
    

    向上面提取出所有相同的代码,放到一个方法中,把不相同的部分,定义成响应的方法。不论以后需要怎么改需求只需要更改Calcute 方法就行了,这样写代码的灵活性是不是更高,可扩展性是不是有了提升。

    下面介绍一下C#定义好的委托:
    1、Action delegate 封装一个方法,该方法没有返回值。其中可以有0~16个参数。
    pubilc delegate void Action(T obj); // T 泛型

    2、Func<T, TResult> delegate 封装一个带有0~16个参数,且返回TResult类型的方法
    public delegate TResult Func();

    同时委托还有协变和逆变,下会再聊!

  • 相关阅读:
    【JAVA】日志管理slf4j
    【JAVA】从java线程来看java内存模型
    【数据结构】---栈和队列
    【数据结构】---链表
    C++ 第10章 反省程序与C++标准模板库
    回忆C++知识点(1)
    C++ 第8章 多态性
    C++ 第7章 继承与派生
    C++ 第6章 数组、指针、字符串
    C++ 第5章 数据的共享与保护
  • 原文地址:https://www.cnblogs.com/lyswwb/p/11700672.html
Copyright © 2011-2022 走看看