写下这篇文章的时候已经是工作三年,突然发现自己从始至终都没有学习过任何东西,突然想学点东西又不知道从何而写那只能一个个基础重新学习。
委托
什么是委托?
委托是一个类,它定义了方法的类型,使得可以将方法当作另一个方法的参数来进行传递,这种将方法动态地赋给参数的做法,可以避免在程序中大量使用If-Else(Switch)语句,同时使得程序具有更好的可扩展性。(百度告诉我的)
自己又想了想委托不就是把方法当成一个类型传到方法中吗
通过下面这个例子我们来回顾下委托。
string[] strs = { "abcdEfG","Hjklwer"};
/// 1)一个字符串数组,将字符转换成小写
/// 2)一个字符串数组,将字符转换成大写
/// 3)一个字符串数组,将字符前后加双引号
首先说下:我是个程序员届的小学生,如有错误或者不地道的地方请谅解
我们看下这三个方法怎么实现
public static void ToLower(string[] str)
{
for (int i = 0; i < str.Length; i++)
{
str[i] = str[i].ToLower();
}
}
public static void ToUpper(string[] str)
{
for (int i = 0; i < str.Length; i++)
{
str[i] = str[i].ToUpper();
}
}
public static void ToSYH(string[] str)
{
for (int i = 0; i < str.Length; i++)
{
str[i] = "\"" + str[i] + "\"";
}
}
通过上面的这三个方法我们发现三个方法很相似只有一处是不同的。
str[i] = str[i].ToLower();
str[i] = str[i].ToUpper();
str[i] = "\"" + str[i] + "\"";
只是这三个方法不同如果我们能将str[i].ToLower()、str[i].ToUpper()、"\"" + str[i] + "\"" 当成方法传进一个方法多好。
首先我们重新写个方法将原来的方法干掉。
public static void ToZhuanHuan(string[] str,'')
{
for (int i = 0; i < str.Length; i++)
{
str[i] ='';
}
}
我们就差把方法传进来了
我们再定义一下str[i]='';传进来的方法;
我们发现只不过是传进来三个方法:将一个string转换成大写、小写、加双引号。
public static string ToLower(string str)
{
return str.ToLower();
}
public static string ToUpper(string str)
{
return str.ToUpper();
}
public static string ToSyh(string str)
{
return "\"" + str + "\"";
}
好,三个方法都定义好了,现在我们就差将方法传进来了。我们可以像以下的方法传
public static void ToZH(string[] str)
{
for (int i = 0; i < str.Length; i++)
{
str[i] = ToLower(str[i]);
}
}
str[i] = ToLower(str[i]);这样传实现是实现了但是要三个转换就又要写三个方法,这样也太不智能了。不行我要是能把方法当成参数传进去该有多好。就像string[] str一样。
那么委托来了
首先我们要定义一个委托
public delegate string DelZhuanHuan(string str);
定义委托时关键词delegate,类型要和你的方法类型一样
public static string ToLower(string str)
{
return str.ToLower();
}
那么你的委托也只能是string 你的ToLower方法也是传入string 那你定义的委托也要是委托
委托定义好了那么我们现在将委托传入你刚才写的ToZH方法吧
public static void ToZH(string[] str,DelZhuanHuan del)
{
for (int i = 0; i < str.Length; i++)
{
str[i] = del(str[i]);
}
}
下面我们要调用这个新方法看看打印出来什么玩意吧
static void Main(string[] args)
{
string[] strs = { "abcdEfG","Hjklwer"};
ToZH(strs,ToLower);
foreach (var item in strs)
{
Console.WriteLine(item);
}
Console.ReadKey();
}
abcdefg
hjklwer
成功是成功了但是发现方法没变少啊!
那么下面我们从另一个例子看下
例:传入两个参数求两个参数之和
public static int Add(int a,int b)
{
return a + b;
}
我们用委托写下
public delegate int DelAdd(int a,int b);
static void Main(string[] args)
{
DelAdd dell = new DelAdd(Add);
dell(1,2);
Console.WriteLine(c);
}
我们现在不想要写Add方法了
干掉
那我们这样写既然我们不想写Add了,那我们要运行一个方法返回两个值的和那就直接写这个方法吧。
static void Main(string[] args)
{
DelAdd dell = new DelAdd(Add);
dell(1,2);
DelAdd del = new DelAdd(delegate(int a,int b) { return a + b; });
int c= del(1,4);
Console.WriteLine(c);
}
我们在实例化这个委托的时候 我们直接写了这个方法
DelAdd del = new DelAdd(delegate(int a,int b) { return a + b; });
其实这个写法和下面这个写法一样的
DelAdd del1 = delegate (int a, int b) { return a + b; };
这就是匿名委托
不用再写Add方法了
但是还是没有优化啊 我特么也不想写委托 每次都写烦死了
微软大大想了想。好吧给你们几个通用的委托吧 这就创造了泛型委托Action,Func
我们看下func的标签
public delegate TResult Func<in T1, in T2, out TResult>(T1 arg1, T2 arg2);
微软给我们自动定义了一个泛型委托
那我们不用自己定义委托了那么接下来怎么写呢
Func<int, int, int> func1 = delegate (int a,int b) { return a + b; };
我们来看下lambda怎么写
Func<int, int, int> func2 = (int a, int b)=>{ return a + b; };
我们不想要定义的类型 ,因为泛型会自动给我们转成对于的类型继续优化
Func<int, int, int> func3 = (a, b) => { return a + b; };
我不想要return了
Func<int, int, int> func4 = (a, b) => a + b;
如果请求参数只是一个值的时候 我们还可以更加省略
Func<int, int> func5 = a => a * 2;
是不是很简单了
来我们再回头看下之前的那个转换成小写和大写的那个方法
刚才就看他不爽了我们能不能用泛型进行优化呢
我们先用匿名函数写下
public delegate void DelTo(string[] str);
DelTo del = delegate(string[] str1) {
for (int i = 0; i < str1.Length; i++)
{
str1[i] = str1[i].ToLower();
}
};
我们不想定义委托了那么我们就使用泛型吧
Action<string[]> action1 = (string[] str1) => {
for (int i = 0; i < str1.Length; i++)
{
str1[i] = str1[i].ToLower();
}
};
总结:lambda就是从匿名委托而来
浙公网安备 33010602011771号