IT教程 ·

c#学习条记之委托

django中Template语言

托付

近来本身在调试C#项目,发明常常能够看到托付和lambda表达式,种种花狸狐哨的写法把我给整的云里雾里的,因而本身特地花了一点工夫来整顿关于delegate的相干学问,轻易本身往后查阅。

作甚托付

托付是.NET中的寻址要领,和C++的函数指针很像;然则托付是范例平安的类,定义了返回范例和参数范例,也就是说托付一种用户自定义的范例,和一般的类一样;

托付的运用

声明托付

    delegate void IntMethodInvoker(int x);    //定义托付IntMethodInvoker, 参数是int,返回范例void

我们能够把托付当作是一件事变,就是给要领名字和返回范例指定一个别号

从上面的例子能够总结出声明托付的模板以下:

  • delegate + 返回范例 + 托付范例名 + 参数列表

托付的运用

实例化托付,而且须要对其举行初始化,如许能够相似地当作一个变量运用了,下面给出一个详细的例子来申明怎样运用托付。

    using System;
    
    namespace DelegateSamples{
    
        delegate double DoubleOp(double x);    // 声明一个托付范例
        class MathOperations
        {
            public static doube MultiplyByTwo(double value)
                return value * 2;
    
            public static double Square(double value)
                return value * value;
        }
        
        class Program
        {
            static void Main()
            {
                // 声明一个托付数组,就像一般数组一样
                DoubleOp[] operations = {MathOperations.MultiplyByTwo, MathOperations.Square};
                
                for(int i = 0; i < operations.length; i++)
                {
                    Console.WriteLine("using operations[{0}]:", i);
                    ProcessAndDisplayNumber(operations[i], 3.2);
                    Console.WriteLine();
                }
            }
        
            static void ProcessAndDisplayNumber(DoubleOp action, double value)
            {
                double res = action(value);         // 挪用action现实封装的要领
                Console.WrireLine("Value is {0}, result of operation is {1}", value, res);
            }
         }

在挪用托付的时刻,末了推断托付是不是为null,不然大概会引起非常

Action 和Func 托付

Action<T>托付表示援用一个void返回范例的要领,Action<T>有许多种变体,Action<in T>挪用带一个参数的要领,没有泛型参数的Action类挪用不带参数的要领;
Func<T>托付相似,表示援用带返回范例的要领,Func<T>也有许多变体,Func<Out TResult>表示挪用带返回范例但没有参数的要领,Func<in T, out TRsult>挪用一个带参数的要领,以此类推;

// 声明一个返回double范例,而且带一个double参数的托付
Func <double, double> operations = {MathOperations.MultiplyByTwo, MathOperations.Square};

// 注重这个要领和上面要领的不一样,利用了Func类
static void ProcessAndDisplayNumber(Func <double, double> action, double value)
{
        double res = action(value);         // 挪用action现实封装的要领
        Console.WrireLine("Value is {0}, result of operation is {1}", value, res);
}

多播托付

在之前的例子中,每一个托付都只含有一个要领挪用,也就是说挪用多少次托付就是挪用多少次要领。

然则,一个托付也能够包括多个要领,这类托付叫做多播托付,因而,这类托付必需返回void,不然返回的数据是不对的

    Action<double> operations = MathOperations.MultiplyByTwo;
    operations += MathOperations.Square;    //这里在给托付增加一个要领
    

关于多播托付的运用,挪用要领链的次序并没获得正式定义,这要求我们只管防止依靠特定次序挪用要领的代码;

从上面的例子能够晓得,多播托付是能够辨认+,+=,-,-=这些标记的,下面给出详细的表示:

  • +=: 表示托付新增一个要领
  • -=: 表示托付削减一个要领

匿名要领

在上面的例子中,托付所挪用的要领,都是我们本身预先写好的,然则托付也能够运用匿名要领,也就是将匿名要领用作托付的参数,这在实例化托付的会有一些不一样的,详细以下面例子所示:

    string name = "";
    
    // Func<string, string>托付接收一个string参数,返回一个string,注重匿名要领的完成,delegate开头
    Func<string, string> anonDel = delegate(string param){
        param += name;
        param += "just for test";
        return param;
    };

运用匿名要领须要恪守的划定规矩:

  1. 在匿名要领中不能运用跳转语句(goto、break、continue),匿名要领外部的语句也不能跳转到匿名要领内部;
  2. 在匿名要领中不能接见不完全的代码,也不能接见在匿名要领外部定义的ref、out参数;

在C#3.0以后,lambda表达式替换了匿名要领,写起来以为更惬意;

Lambda表达式

lambda表达式主假如用来替换匿名要领的,由于明显托付晓得他本身须要挪用的是什么要领,不须要声明delegate关键字,在参数和要领体之间插进去=>,表示“goes to",详细示例以下所示:

    string name = "";
    
    // Func<string, string>托付接收一个string参数,返回一个string,这里运用lambda表达式
    Func<string, string> anonDel = param => {
        param += name;
        param += "just for test";
        return param;
    };
   // 如许的lambda表达式是不是是很文雅,就是调试程序的时刻会有点烦
   

为了更好地运用lambda表达式,轻易我们本身写代码写的花里花梢的,就对其多做一点引见:

参数

  1. 假如只要一个参数,就只须要写出参数名字就行
     Func<string, string> oneParam = s => String.Format("change to Upper {0}", s.ToUpper());
  2. 运用多个参数,就把参数用写在()里
    Func<double, double, double> twoParams= (x, y) => x * y;    // 返回x*y

在运用多个参数的时刻,我以为照样在参数前面加上范例比较好,便于明白,比方(double x, double y) => x * y;

多行代码

  1. 只要一条语句,要领内里不须要{}和return,编译器会自动增加一个隐式的return
     Func<double, double, double> result = x, y => x * y;
  2. 含有多条语句,须要加上{}和return
    string lastname = "Alex";
    Func<string ,string> printName = name =>
        {
            name += lastname;
            return String.Format("Being Upper: {0}",name);
        }

TCP协议

参与评论