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;
};
运用匿名要领须要恪守的划定规矩:
- 在匿名要领中不能运用跳转语句(goto、break、continue),匿名要领外部的语句也不能跳转到匿名要领内部;
- 在匿名要领中不能接见不完全的代码,也不能接见在匿名要领外部定义的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表达式,轻易我们本身写代码写的花里花梢的,就对其多做一点引见:
参数
- 假如只要一个参数,就只须要写出参数名字就行
Func<string, string> oneParam = s => String.Format("change to Upper {0}", s.ToUpper());
- 运用多个参数,就把参数用写在()里
Func<double, double, double> twoParams= (x, y) => x * y; // 返回x*y
在运用多个参数的时刻,我以为照样在参数前面加上范例比较好,便于明白,比方(double x, double y) => x * y;
多行代码
- 只要一条语句,要领内里不须要{}和return,编译器会自动增加一个隐式的return
Func<double, double, double> result = x, y => x * y;
- 含有多条语句,须要加上{}和return
string lastname = "Alex"; Func<string ,string> printName = name => { name += lastname; return String.Format("Being Upper: {0}",name); }
TCP协议