为什么要用委托delegate,lambda,action,func

分类: 篮球体育比分365 时间: 2025-10-17 18:17:38 作者: admin 阅读: 3050 点赞: 642
为什么要用委托delegate,lambda,action,func

1、为什么要用委托

我们为什么要有委托?任何东西存在即合理,不合理的也会被时间淘汰掉,委托既然存在肯定有存在的必要,我们来看一下什么时候可以用到委托。

接下来我们有个需求,就是调用一个方法,取出1-1000个数字中所有是10的倍数的数字

public static List GetNum() {

List lst = new List();

//这个算法是最简陋的,但是举这个例子是最合适的

for (int i = 1; i < 1000; i++)

{

if (i%10==0) {

lst.Add(i);

}

}

return lst;

}

这个很好写,但是如果有一天,我们的需求变了,想取出1-1000个数字中所有是8的倍数的数字,那我们应该怎么写?是不是只要将if里面的条件改为i%8==0就行了,但是有一点变动的话就修改方法,说明这个方法写的并不好,如果方法很复杂的话修改也很艰难。可能有人会说在添加一个获取是8的倍数的方法,这样的话会增加数据冗余,也就是重复的内容。

如果我们可以传递方法的话,只要传过来一个(有一个参数为int类型返回值为Boolean类型的方法),这个问题将不是问题

public static List GetNum(有一个int类型的参数返回值为Boolean类型的方法) {

List lst = new List();

for (int i = 1; i < 1000; i++)

{

if (有一个int类型的参数返回值为Boolean类型的方法) {

lst.Add(i);

}

}

return lst;

}

是不是我们将想要获取什么样的数字这个操作来交给了调用者,无论调用者想获取1-1000以内什么样的数字都可以完成。但是这个方法的前提就是可以传递方法,这个时候我们就需要用到委托了。

2、委托如何使用

委托其实就是一个能够指向方法的 指针,定义了一个委托就是定义了一个 类型

首先我们先来定义一个委托,也就是定义一个类型

//访问修饰符 委托关键字 方法的返回值类型 要定义的类型名(参数1,参数2.....);

public delegate Boolean DelegateFunc(int x);

委托定义好了,也就是说我们已经定义好了一个DelegateFunc类型,这个类型的使用方法就和public class DelegateFunc{}写了一个类是一样的,因为都是定义了一个类型,既然大家都是类型,那用法肯定都是一样的,我们先来看一下声明普通的类型是如何声明的

//类型 变量名 = 实例化一个Object类型的对象(构造函数有无参数)

Object obj = new Object();

而DelegateFunc既然也是我们定义好的一个类型,那用法自然一样(因为构造函数需要参数,所以下面这样写是不对的,没有传入参数)

//类型 变量名 = 实例化一个DelegateFunc类型的对象(构造函数有无参数)

DelegateFunc func = new DelegateFunc();

委托是一个能够指向方法的指针,而它的构造函数就是需要一个方法,接着我们来定义一个返回值为Boolean,能接收一个int类型参数的方法

//相当于方案1

public static Boolean Condition1(int i)

{

//模拟复杂的操作 相当于return i%10==0;

int x = i % 10;

if (i % 10 == 0)

{

return true;

}

else {

return false;

}

}

定义好了方法我们再来实例化一个DelegateFunc类型的对象

//构造函数放入方法的话不需要带(),带()的话是调用

DelegateFunc func = new DelegateFunc(Condition1);

下面看一下下面这种声明委托类型的方式

//同样都是类型Object类型可以这样写

//因为String最终是继承自Object,并且String可以默认转换为Object

Object obj = "obj";

//而DelegateFunc也可以通过这种方式赋值,这说明Condition1可以默认转换为委托类型

DelegateFunc func = Condition1;

实例化完成之后func变量就会指向Condition1方法,调用方式如下

//调用委托类型的对象和调用普通的方法是一样的

func(10);

然后我们把刚才写的GetNum方法修改为如下的样子,参数为接收一个DelegateFunc类型的参数,也就是委托类型

public static List GetNum(DelegateFunc func)

{

List lst = new List();

for (int i = 1; i < 1000; i++)

{

//调用传过来的方法,根据调用者传过来的方法拿到想要的数字

if (func(i))

{

lst.Add(i);

}

}

return lst;

}

在Main方法中调用GetNum方法

//声明委托

DelegateFunc func = new DelegateFunc(Condition1);

//调用方法

List lst = GetNum(func);

//也可以直接调用,因为都会默认转换

//List lst = GetNum(Condition1);

//输出

foreach (int item in lst)

{

Console.WriteLine(item);

}

输出

如果我们有新的方案的话,只需要在新建一个方案,然后传入方法中,比如我们还看刚才那个求1-1000以内8的倍数,我们只需要声明一个新的方案

//声明一个新的方案2

public static Boolean Condition2(int i) {

//同样模拟复杂的操作 相当于return i%8==0;

int x = i % 8;

if (i % 8 == 0)

{

return true;

}

else {

return false;

}

}

然后和刚才一样,声明一个委托就行,传入GetNum就行。

不过我们看一下,虽然已经比较简化代码了,但是写起来还是很麻烦,然后我们来看一下lambda表达式

3、lambda表达式

首先lambda表达式只是方法的一种写法!lambda声明的方法是匿名方法,它和委托并不是绑死的,这是两个东西,但是lambda表达式和委托结合使用是非常常见的!

看一下lambda表达式的语法,也就是函数的另一种写法

//可以这样写

//DelegateFunc func = new DelegateFunc((i) =>

//{

// return i % 8 == 0;

//});

//也可以这样 不进行new DelegateFunc操作,因为会默认转换

//如果有多句的话,这样写每一句通过分号隔开

DelegateFunc func = (i) => { return i % 8 == 0; };

//如果只有单句 不用写return 默认reuturn i%8==0 这一句计算出来的值

func = (i) => i % 8 == 0;

//如果只有一个参数 多个参数的话要(i,j,....)这样写

func = i => i % 8 == 0;

除此之外lambda也可以用来声明方法,貌似只能写一句,,,,

//无返回值

public static void HelloWord() => Console.WriteLine("Hello Word!");

//有返回值

public static String GetHelloWord() => "Hello Word!";

有了lambd我们再来调用GetNum,就会变得非常方便

//8的倍数

List lst = GetNum((i) => i % 8 == 0);

//10的倍数

lst = GetNum(i => i % 10 == 0);

//20的倍数

lst = GetNum(i => i % 20 == 0);

4、Action和Func

Action和Func是微软已经定义好的的两种委托类型,区别是Action是没有返回值的,而Func是需要返回值的

Action使用方法

//无参数

Action action1 = () => Console.WriteLine("action");

//有参数的话调用Action

Action action2 = (i) => Console.WriteLine(i);

//多个参数就在生命的时候

Action action3 = (i, str) => Console.WriteLine(i+"\t"+str);

//调用

action1();

action2(10);

action3(10,"s");

运行结果:

Func使用方法

//Func是没有Func类型的,只有Func类型

Func func1 = () => "func";

//如果需要参数 Func

//最后一个T类型为返回值类型,前面的全都为参数的类型!!!

Func func2 = (i) => int.Parse(i);

//如果有多个参数 最后一个T类型为返回值类型,前面的全都为参数的类型!!!

Func func3 = (i, str) => int.Parse(i + str);

//调用

Console.WriteLine(func1());

Console.WriteLine(func2("123"));

Console.WriteLine(func3(1,"23"));

1、为什么要用委托

我们为什么要有委托?任何东西存在即合理,不合理的也会被时间淘汰掉,委托既然存在肯定有存在的必要,我们来看一下什么时候可以用到委托。

接下来我们有个需求,就是调用一个方法,取出1-1000个数字中所有是10的倍数的数字

public static List GetNum() {

List lst = new List();

//这个算法是最简陋的,但是举这个例子是最合适的

for (int i = 1; i < 1000; i++)

{

if (i%10==0) {

lst.Add(i);

}

}

return lst;

}

这个很好写,但是如果有一天,我们的需求变了,想取出1-1000个数字中所有是8的倍数的数字,那我们应该怎么写?是不是只要将if里面的条件改为i%8==0就行了,但是有一点变动的话就修改方法,说明这个方法写的并不好,如果方法很复杂的话修改也很艰难。可能有人会说在添加一个获取是8的倍数的方法,这样的话会增加数据冗余,也就是重复的内容。

如果我们可以传递方法的话,只要传过来一个(有一个参数为int类型返回值为Boolean类型的方法),这个问题将不是问题

public static List GetNum(有一个int类型的参数返回值为Boolean类型的方法) {

List lst = new List();

for (int i = 1; i < 1000; i++)

{

if (有一个int类型的参数返回值为Boolean类型的方法) {

lst.Add(i);

}

}

return lst;

}

是不是我们将想要获取什么样的数字这个操作来交给了调用者,无论调用者想获取1-1000以内什么样的数字都可以完成。但是这个方法的前提就是可以传递方法,这个时候我们就需要用到委托了。

2、委托如何使用

委托其实就是一个能够指向方法的 指针,定义了一个委托就是定义了一个 类型

首先我们先来定义一个委托,也就是定义一个类型

//访问修饰符 委托关键字 方法的返回值类型 要定义的类型名(参数1,参数2.....);

public delegate Boolean DelegateFunc(int x);

委托定义好了,也就是说我们已经定义好了一个DelegateFunc类型,这个类型的使用方法就和public class DelegateFunc{}写了一个类是一样的,因为都是定义了一个类型,既然大家都是类型,那用法肯定都是一样的,我们先来看一下声明普通的类型是如何声明的

//类型 变量名 = 实例化一个Object类型的对象(构造函数有无参数)

Object obj = new Object();

而DelegateFunc既然也是我们定义好的一个类型,那用法自然一样(因为构造函数需要参数,所以下面这样写是不对的,没有传入参数)

//类型 变量名 = 实例化一个DelegateFunc类型的对象(构造函数有无参数)

DelegateFunc func = new DelegateFunc();

委托是一个能够指向方法的指针,而它的构造函数就是需要一个方法,接着我们来定义一个返回值为Boolean,能接收一个int类型参数的方法

//相当于方案1

public static Boolean Condition1(int i)

{

//模拟复杂的操作 相当于return i%10==0;

int x = i % 10;

if (i % 10 == 0)

{

return true;

}

else {

return false;

}

}

定义好了方法我们再来实例化一个DelegateFunc类型的对象

//构造函数放入方法的话不需要带(),带()的话是调用

DelegateFunc func = new DelegateFunc(Condition1);

下面看一下下面这种声明委托类型的方式

//同样都是类型Object类型可以这样写

//因为String最终是继承自Object,并且String可以默认转换为Object

Object obj = "obj";

//而DelegateFunc也可以通过这种方式赋值,这说明Condition1可以默认转换为委托类型

DelegateFunc func = Condition1;

实例化完成之后func变量就会指向Condition1方法,调用方式如下

//调用委托类型的对象和调用普通的方法是一样的

func(10);

然后我们把刚才写的GetNum方法修改为如下的样子,参数为接收一个DelegateFunc类型的参数,也就是委托类型

public static List GetNum(DelegateFunc func)

{

List lst = new List();

for (int i = 1; i < 1000; i++)

{

//调用传过来的方法,根据调用者传过来的方法拿到想要的数字

if (func(i))

{

lst.Add(i);

}

}

return lst;

}

在Main方法中调用GetNum方法

//声明委托

DelegateFunc func = new DelegateFunc(Condition1);

//调用方法

List lst = GetNum(func);

//也可以直接调用,因为都会默认转换

//List lst = GetNum(Condition1);

//输出

foreach (int item in lst)

{

Console.WriteLine(item);

}

输出

如果我们有新的方案的话,只需要在新建一个方案,然后传入方法中,比如我们还看刚才那个求1-1000以内8的倍数,我们只需要声明一个新的方案

//声明一个新的方案2

public static Boolean Condition2(int i) {

//同样模拟复杂的操作 相当于return i%8==0;

int x = i % 8;

if (i % 8 == 0)

{

return true;

}

else {

return false;

}

}

然后和刚才一样,声明一个委托就行,传入GetNum就行。

不过我们看一下,虽然已经比较简化代码了,但是写起来还是很麻烦,然后我们来看一下lambda表达式

3、lambda表达式

首先lambda表达式只是方法的一种写法!lambda声明的方法是匿名方法,它和委托并不是绑死的,这是两个东西,但是lambda表达式和委托结合使用是非常常见的!

看一下lambda表达式的语法,也就是函数的另一种写法

//可以这样写

//DelegateFunc func = new DelegateFunc((i) =>

//{

// return i % 8 == 0;

//});

//也可以这样 不进行new DelegateFunc操作,因为会默认转换

//如果有多句的话,这样写每一句通过分号隔开

DelegateFunc func = (i) => { return i % 8 == 0; };

//如果只有单句 不用写return 默认reuturn i%8==0 这一句计算出来的值

func = (i) => i % 8 == 0;

//如果只有一个参数 多个参数的话要(i,j,....)这样写

func = i => i % 8 == 0;

除此之外lambda也可以用来声明方法,貌似只能写一句,,,,

//无返回值

public static void HelloWord() => Console.WriteLine("Hello Word!");

//有返回值

public static String GetHelloWord() => "Hello Word!";

有了lambd我们再来调用GetNum,就会变得非常方便

//8的倍数

List lst = GetNum((i) => i % 8 == 0);

//10的倍数

lst = GetNum(i => i % 10 == 0);

//20的倍数

lst = GetNum(i => i % 20 == 0);

4、Action和Func

Action和Func是微软已经定义好的的两种委托类型,区别是Action是没有返回值的,而Func是需要返回值的

Action使用方法

标题

//无参数

Action action1 = () => Console.WriteLine("action");

//有参数的话调用Action

Action action2 = (i) => Console.WriteLine(i);

//多个参数就在生命的时候

Action action3 = (i, str) => Console.WriteLine(i+"\t"+str);

//调用

action1();

action2(10);

action3(10,"s");

运行结果:

Func使用方法

//Func是没有Func类型的,只有Func类型

Func func1 = () => "func";

//如果需要参数 Func

//最后一个T类型为返回值类型,前面的全都为参数的类型!!!

Func func2 = (i) => int.Parse(i);

//如果有多个参数 最后一个T类型为返回值类型,前面的全都为参数的类型!!!

Func func3 = (i, str) => int.Parse(i + str);

//调用

Console.WriteLine(func1());

Console.WriteLine(func2("123"));

Console.WriteLine(func3(1,"23"));

运行结果

运行结果

相关推荐