您的位置:首页 > 其它

多播委托的使用举例、出现异常时多播委托需要用迭代方法列表、匿名方法、lambda表达式

2017-08-08 18:39 435 查看
多播委托:

是指委托可以包含多个方法,如果调用多播委托,可以按顺序连续调用多个方法。为此,委托的签名就必须返回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();
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐