• 浅析C#中的托付


    托付是寻址方法的.NET版本号。在C++中。函数指针仅仅只是是一个指向内存位置的指针,它不是类型安全的。而.NET托付全然不同,托付是安全类型的类,它定义了返回类型和參数的类型。
    当把方法传递给其它方法时,须要使用托付。

    C#中使用一个类时,分两个阶段。

    首先须要定义这个类,即告诉编译器这个类由什么组成的。然后,实例化一个对象(除非仅仅使用静态方法)。

    对于托付也是相似,也须要两个步骤。

    首先必须定义要使用的托付。然后必须创建该托付的一个或多个实例。

    定义语法:

    delegate void IntMethodInoker(int x);
    delegate double TwoLongsOp(long first, long second);
    delegate string GetString();

    定义托付基本上是定义一个新类。所以能够在定义类的不论什么同样地方定义托付。即能够在还有一个类的内部定义,能够在不论什么类的外部定义,能够在名称空间中把托付定义为顶层对象。

    依据托付定义的可见性,和托付的作用域,能够在托付的定义上应用随意常见的訪问修饰符:public、private、protected等
    比如:

    public delegate string GetAString();

    使用托付:

    private delegate string GetAString();
    static void Main()
    {
        int x=40;
        GetAString firstStringMethod = new GetAString(x.ToString);
        Console.WriteLine("String is {0}",firstStringMethod () );
    }

    由上述代码能够看到。C#的托付在语法上总是接受一个參数的构造函数。这个參数就是托付引用的方法,可是这种方法必须匹配最初定义托付时的签名。

    实际上。给托付实例提供圆括号与调用托付类的Invoke()方法全然同样。

    使用Invoke完毕一个托付方法的封送。就相似于使用SendMessage方法来给界面线程发送消息,是一个同步方法。也就是说在Invoke封送的方法被运行完毕前,Invoke方法不会返回,从而调用者线程将被堵塞。

    由于firstStringMethod 是一个托付类型的变量,所以C#编译器会用firstStringMethod.Invoke()取代firstStringMethod ()。

    firstStringMethod();
    firstStringMethod.Invoke();

    为了降低输入量。仅仅须要托付实例,就能够仅仅传递地址的名称,即托付判断

    GetAString firstStringMethod = new GetAString(x.ToString);
    GetAString firstStringMethod = x.ToString;

    注意:输入行事不能是x.ToString()。也不能把它传给托付变量。x.ToString表示把方法的地址赋予托付变量。

    多播托付:
    托付能够包括多个方法,这样的托付称为多播托付。假设调用多播托付。就能够按顺序连续调用多个方法。可是,托付的签名必须返回void。否则仅仅能得到托付调用的最后一个方法的结果。


    多播托付演示样例程:

    delegate void Delegate_Multicast(int x, int y);
    Class Class2
    {
        static void Method1(int x, int y) 
        {
          Console.WriteLine("You r in Method 1");
        }
        static void Method2(int x, int y) 
        {
          Console.WriteLine("You r in Method 2");
        }
        public static void Main() 
        {
          Delegate_Multicast func = new Delegate_Multicast(Method1);
          func += new Delegate_Multicast(Method2);
          func(1,2);             // Method1 and Method2 are called
          func -= new Delegate_Multicast(Method1);
          func(2,3);             // Only Method2 is called
       }
    }    

    解析:
    上面的演示样例程序分别定义了名为method1 和 method2的两个接受整型參数、返回类型为void的方法。
    在Main函数里使用以下的声明创建托付对象:
    Delegate_Multicast func = new Delegate_Multicast(Method1);
    然后使用+= 来加入托付,使用-=来移除托付。

    合并托付:
    托付对象的一个用途在于,能够使用 + 运算符将它们分配给一个要成为多路广播托付的托付实例。

    组合的托付可调用组成它的那两个托付。

    仅仅有同样类型的托付才干够组合。
    - 运算符可用来从组合的托付移除组件托付。

    delegate void Del(string s);
    
    class TestClass
    {
        static void Hello(string s)
        {
            System.Console.WriteLine("  Hello, {0}!", s);
        }
    
        static void Goodbye(string s)
        {
            System.Console.WriteLine("  Goodbye, {0}!", s);
        }
    
        static void Main()
        {
            Del a, b, c, d;
    
            // Create the delegate object a that references 
            // the method Hello:
            a = Hello;
    
            // Create the delegate object b that references 
            // the method Goodbye:
            b = Goodbye;
    
            // The two delegates, a and b, are composed to form c: 
            c = a + b;
    
            // Remove a from the composed delegate, leaving d, 
            // which calls only the method Goodbye:
            d = c - a;
    
            System.Console.WriteLine("Invoking delegate a:");
            a("A");
            System.Console.WriteLine("Invoking delegate b:");
            b("B");
            System.Console.WriteLine("Invoking delegate c:");
            c("C");
            System.Console.WriteLine("Invoking delegate d:");
            d("D");
        }
    }
    
    /*-------------------------
    输出
    Invoking delegate a:
      Hello, A!
    Invoking delegate b:
      Goodbye, B!
    Invoking delegate c:
      Hello, C!
      Goodbye, C!
    Invoking delegate d:
      Goodbye, D!
      ----------------------*/

    匿名方法:
    到眼下为止。要想使用托付工作。方法必须已经存在。可是还有还有一种使用托付的方法:即通过匿名方法。

    匿名方法是用作托付的參数的一段代码。
    用匿名方法定义托付的语法与前面的定义并没有差别。

    但在实例化的时候就有了差别了。


    假设使用匿名方法。则不必创建单独的方法,因此降低了实例化托付所需的编码系统开销。

    比如。假设创建方法所需的系统开销是不必要的,在托付的位置指定代码块就非常实用。启动新线程即是一个非常好的演示样例。无需为托付创建很多其它方法,线程类就可以创建一个线程而且包括该线程运行的代码。

    void StartThread()
    {
        System.Threading.Thread t1 = new System.Threading.Thread
          (delegate()
                {
                    System.Console.Write("Hello, ");
                    System.Console.WriteLine("World!");
                });
        t1.Start();
    }

    托付类型派生自 .NET Framework 中的 Delegate 类。

    托付类型是封装的,它们不能派生出其它类,也不能从 Delegate 派生出自己定义类。 由于实例化的托付是一个对象。因此能够作为參数传递或分配给一个属性。 这同意方法作为參数接受托付并在稍后调用托付。

    这被称为异步回调,是在长进程完毕时通知调用方的经常用法。 当以这样的方式使用托付时。使用托付的代码不须要知道要使用的实现方法。 功能相似于封装接口提供的功能。

  • 相关阅读:
    jquery-ui.min.js:5 Uncaught TypeError: b.nodeName.toLowerCase is not a function
    HTTP::Request
    LWP::UserAgent
    perl json模块
    perl 处理perl返回的json
    perl中 wx返回的json需要encode_utf8($d);
    perl malformed JSON string, neither tag, array, object, number, string or atom, at character offset
    encode_json 会对给定的Perl的数据结构转换为一个UTF-8 encoded, binary string.
    为什么出现Wide character in print at a14.pl line 41
    perl encode_json 会产生 UTF-8 (binary) string decode_json 需要一个 UTF-8 (binary) string
  • 原文地址:https://www.cnblogs.com/yangykaifa/p/7383763.html
Copyright © 2020-2023  润新知