多播委托的使用举例、出现异常时多播委托需要用迭代方法列表、匿名方法、lambda表达式
2017-08-08 18:39
435 查看
多播委托:
是指委托可以包含多个方法,如果调用多播委托,可以按顺序连续调用多个方法。为此,委托的签名就必须返回void,否则,就只能得到委托调用的最后一个方法的结果。多播中添加方法操作可以使用+=
举例:
执行:
多播委托的改进
为了避免发生异常后,后面的委托不能执行的情况,应自己迭代方法列表,使用Delegate类定义GetInvocationList()方法,返回一个Delegate对象数组;使用这个委托调用与委托直接相关的方法,捕获异常,并继续下一次迭代。
修改
匿名方法并没有提高代码的执行效率,如果需要用匿名方法多写编写同一个功能,就不要使用匿名方法。
匿名方法:
两个原则:
1、匿名方法中不能使用跳转语句(break goto continue)跳到该匿名方法的外部,反之亦然,匿名方法外部的跳转语句不能跳到匿名方法的内部;
2、匿名方法内部不能访问不安全的代码,也不能访问在匿名方法外部使用的ref和out参数,但是可以使用在匿名方法外部定义的其他变量。 class Program
{
static void Main()
{
string mid = ",mid part";
Func<string, string> anonDel = delegate(string param)//anonDel是委托类型的变量
{
param += mid;//使用到了匿名方法外定义的变量mid
param += " and this is added to the string";
return param;
};
Console.WriteLine(anonDel("hello"));//hello,mid part and this is added to the string
Console.ReadKey();
}
}
lambda表达式:
static void Main()
{
string mid = ",mid part";
Func<string, string> lambda = param=>//lambda表达式,param是表达式的参数,返回值由return返回,这里lambda是表达式的名字,自己定义
{
param += mid;//使用到了表达式外定义的变量mid
param += " and this is added to the string";
return param;//Func<>必须有一个返回值,所有lambda表达式中必须有个return
};
Console.WriteLine(lambda("hello"));//hello,mid part and this is added to the string,使用表达式的名字进行定义
Console.ReadKey();
}
lambda的表达式的返回值:对于double型,没有return,却能得到返回值,Func<>中必须有返回值,很显然满足这个条件,但是string中必须有return,否则有错误(原因见下面) static void Main()
{
Func<double, double, double> twoParams = (x, y) => x * y;//为什么这里没有return,却能得到返回值
Console.WriteLine(twoParams(2, 3));//6
Console.ReadKey();
}
关于上面的问题终于明白:lambda表达式只有一条语句,在方法块内就不需要花括号和return语句,编译器会自动添加一条隐式的return语句。多条语句需要花括号和return。 static void Main()
{
//lambda表达式只有一条语句,在方法块内就不需要花括号和return语句,编译器会自动添加一条隐式的return语句
Func<double, double, double> twoParams = (x, y) => x* y;
Console.WriteLine(twoParams(2, 3));//6
Func<string, string> lambda3 = (param1) =>param1 += "hello";
Console.WriteLine(lambda3("hello")); //hellohello
Console.ReadKey();
}
了解lambda表达式
static void Main()
{
var values = new List<int>() {10,20,30 };
var funcs = new List<Func<int>>(); //元素为Func<int>委托对象的集合
//向集合funcs中添加委托对象,每个委托对象执行的方法就是返回values中的元素
foreach (var val in values)
{
funcs.Add(()=>val);
}
//遍历调用funcs集合中的每个委托
foreach (var f in funcs)
{
Console.WriteLine(f());
}
Console.ReadKey();
}
是指委托可以包含多个方法,如果调用多播委托,可以按顺序连续调用多个方法。为此,委托的签名就必须返回void,否则,就只能得到委托调用的最后一个方法的结果。多播中添加方法操作可以使用+=
举例:
namespace Ado_net_demo1 { class ClassOperater { public static void One() { Console.WriteLine("One"); throw new Exception("Error in one"); } public static void Two() { Console.WriteLine("two"); } } }
执行:
namespace Ado_net_demo1 { class Program { static void Main() { Action del = ClassOperater.One; del += ClassOperater.Two;//这种方法在发生异常后停止迭代,不继续向下执行 try { del(); } catch (System.Exception ex) { Console.WriteLine(ex); } Console.ReadKey(); } } }
多播委托的改进
为了避免发生异常后,后面的委托不能执行的情况,应自己迭代方法列表,使用Delegate类定义GetInvocationList()方法,返回一个Delegate对象数组;使用这个委托调用与委托直接相关的方法,捕获异常,并继续下一次迭代。
修改
namespace Ado_net_demo1 { class Program { static void Main() { Action del = ClassOperater.One; del += ClassOperater.Two; Delegate[] delegates = del.GetInvocationList(); foreach (Action d in delegates) { try { d(); } catch (System.Exception ex) { Console.WriteLine(ex);//当程序出现异常后,抛出,继续循环 } } Console.ReadKey(); } } }
匿名方法并没有提高代码的执行效率,如果需要用匿名方法多写编写同一个功能,就不要使用匿名方法。
匿名方法:
两个原则:
1、匿名方法中不能使用跳转语句(break goto continue)跳到该匿名方法的外部,反之亦然,匿名方法外部的跳转语句不能跳到匿名方法的内部;
2、匿名方法内部不能访问不安全的代码,也不能访问在匿名方法外部使用的ref和out参数,但是可以使用在匿名方法外部定义的其他变量。 class Program
{
static void Main()
{
string mid = ",mid part";
Func<string, string> anonDel = delegate(string param)//anonDel是委托类型的变量
{
param += mid;//使用到了匿名方法外定义的变量mid
param += " and this is added to the string";
return param;
};
Console.WriteLine(anonDel("hello"));//hello,mid part and this is added to the string
Console.ReadKey();
}
}
lambda表达式:
static void Main()
{
string mid = ",mid part";
Func<string, string> lambda = param=>//lambda表达式,param是表达式的参数,返回值由return返回,这里lambda是表达式的名字,自己定义
{
param += mid;//使用到了表达式外定义的变量mid
param += " and this is added to the string";
return param;//Func<>必须有一个返回值,所有lambda表达式中必须有个return
};
Console.WriteLine(lambda("hello"));//hello,mid part and this is added to the string,使用表达式的名字进行定义
Console.ReadKey();
}
lambda的表达式的返回值:对于double型,没有return,却能得到返回值,Func<>中必须有返回值,很显然满足这个条件,但是string中必须有return,否则有错误(原因见下面) static void Main()
{
Func<double, double, double> twoParams = (x, y) => x * y;//为什么这里没有return,却能得到返回值
Console.WriteLine(twoParams(2, 3));//6
Console.ReadKey();
}
关于上面的问题终于明白:lambda表达式只有一条语句,在方法块内就不需要花括号和return语句,编译器会自动添加一条隐式的return语句。多条语句需要花括号和return。 static void Main()
{
//lambda表达式只有一条语句,在方法块内就不需要花括号和return语句,编译器会自动添加一条隐式的return语句
Func<double, double, double> twoParams = (x, y) => x* y;
Console.WriteLine(twoParams(2, 3));//6
Func<string, string> lambda3 = (param1) =>param1 += "hello";
Console.WriteLine(lambda3("hello")); //hellohello
Console.ReadKey();
}
了解lambda表达式
static void Main()
{
var values = new List<int>() {10,20,30 };
var funcs = new List<Func<int>>(); //元素为Func<int>委托对象的集合
//向集合funcs中添加委托对象,每个委托对象执行的方法就是返回values中的元素
foreach (var val in values)
{
funcs.Add(()=>val);
}
//遍历调用funcs集合中的每个委托
foreach (var f in funcs)
{
Console.WriteLine(f());
}
Console.ReadKey();
}
相关文章推荐
- 冒泡排序C#实现,使用委托,包括三种方式:Fun<>,匿名方法,Lambda表达式
- C# 2.0:使用匿名方法、迭代程序和局部类来创建优雅的代码
- 使用MySQL和Hibernate时,出现java.lang.UnsupportedOperationException: Update queries only supported through HQL异常的解决方法
- 使用Action、Func,EventHandler,params关键字修饰的参数的匿名委托和Lambda表达式
- 事件与委托的匿名方法使用方法示例
- 使用Action、Func,EventHandler,params关键字修饰的参数的匿名委托和Lambda表达式
- C# 2.0:使用匿名方法、迭代程序和局部类来创建优雅的代码
- (转)C#中的委托,匿名方法和Lambda表达式
- C# 2.0:使用匿名方法、迭代程序和局部类来创建优雅的代码
- 从异常{ 无法将 匿名方法 转换为类型“System.Delegate”,因为它不是委托类型 }说开去
- 关于委托:异常{ 无法将 匿名方法 转换为类型“System.Delegate”,因为它不是委托类型 }
- 再谈C#中的委托,匿名方法和Lambda表达式
- C#中的委托,匿名方法和Lambda表达式(转载)
- C#中的委托,匿名方法和Lambda表达式
- .net 使用提取模式使用SQL创建报表 出现“您请求的报表需要更多信息.”的解决方法
- 使用匿名方法、迭代程序和局部类来创建优雅的代码
- 从委托到匿名方法,再到Lambda表达式(1.0-2.0-3.0的根中委托写法)
- C#中使用委托表达式与匿名方法实现委托方法
- (装载)C#中的委托,匿名方法和Lambda表达式
- C# 2.0:使用匿名方法、迭代程序和局部类来创建优雅的代码