c# 委托 Func Action
委托的意义:
扩展性、封装性、灵活性,专注于逻辑层面
注意委托的声明位置,委托是类,与class平行关系,声明在class内为嵌套类。
public static void Sayhello() { Console.WriteLine("你好啊委托"); } public delegate void dlg(); //注意委托的声明位置,委托是类,与class平行关系,声明在class内为嵌套类。 static void Main(string[] args) { dlg Onedlg = new dlg(Sayhello); Onedlg(); }
匿名委托
在 C# 语言中匿名委托是指使用匿名方法注册在委托上,实际上是在委托中通过定义代码块来实现委托的作用,具体的语法形式如下。
//1. 定义委托
修饰符 delegate 返回值类型 委托名 ( 参数列表 );
//2. 定义匿名委托
委托名 委托对象 = delegate
{
//代码块
};
3. 调用匿名委托
通过上面 3 个步骤即可完成匿名委托的定义和调用,需要注意的是,在定义匿名委托时代码块结束后要在 {} 后加上分号。
下面通过实例来演示匿名委托的应用。
【委托】使用匿名委托计算长方形的面积。
根据题目要求,代码如下。
class Program { public delegate void AreaDelegate(double length, double width); static void Main(string[] args) { Console.WriteLine("请输入长方形的长:"); double length = double.Parse(Console.ReadLine()); Console.WriteLine("请输入长方形的宽:"); double width = double.Parse(Console.ReadLine()); AreaDelegate areaDelegate = delegate { Console.WriteLine("长方形的面积为:" + length * width); }; //分号 areaDelegate(length, width); } }
在使用匿名委托时并没有定义方法,而是在实例化委托时直接实现了具体的操作。
由于匿名委托并不能很好地实现代码的重用,匿名委托通常适用于实现一些仅需要使用一次委托中代码的情况,并且代码比较少。
c#已定义委托
Func可以接受0个至16个传入参数,必须具有返回值。
Action可以接受0个至16个传入参数,无返回值。
Predicate只能接受一个传入参数,返回值为bool类型。
class Program { public static void SayHello() { Console.WriteLine("hello,world!"); } public static void SayGoodbye(int today,string goodbye) { Console.WriteLine($"{goodbye},{today}天"); } public static string CalCulate(int a,int b ) { return "结果为:"+a+b; } public static string SayHello2() { return "hello,world"; } static void Main(string[] args) { //action 有或无参数,无返回结果 Action acton1 = new Action(SayHello); Action<int, string> actin2 = new Action<int, string>(SayGoodbye); //func 有或者无参数,有返回值 Func<string> func2 = new Func<string>(SayHello2); Func<int,int,string> func1 = new Func<int,int,string>(CalCulate); //调用 名称.invoke() actin2.Invoke(1, "你好"); func2.Invoke(); Console.ReadLine(); } }
格式:
Func<TResult>,Func(T1, T2, T3, TResult) 委托
Action ,Action<T1, T2>
Predicate 委托常用于检索 collection,下面是 Predicate 的语法结构。
值得注意的是, Predicate<T> 差不多等价于 Func<T,bool>。
模板方法:
工厂流水线,中间填空用委托填入不同产品(返回值)。
回调方法:
在上面例子增加记录log方法,回调一般位于末尾,而且没有返回值
多播委托:
delegate1 += delegate2
delegate1 -= delegate2
显式 异步调用:
1.老方法 thread
带参数(一个object)时:
Thread a = new Thread(SayGoodbye);
a.Start(2);
public static void SayGoodbye(object today)
{
Console.WriteLine($"{today}天");
}
解释:
如果新线程上运行带参数的方法,那么需要用到ParameterizedThreadStart委托,
ParameterizedThreadStart定义:public delegate void ParameterizedThreadStart(object obj);
一:要求只能有一个参数,且为object类型
二:无返回值
Thread th=new Thread(Test)和Thread th =new Thread(ParameterizedThreadStart(Test))一样。
Thread th=new Thread(Test)和 Thread th=new Thread(ThreadStart(Test))有什么区别?
其中:
Void Test()
{
//xxxxxx
}
两者没有区别,前者是C#的语法,后者是.Net的语法,编译器会自动把前者转换成后者。
ThreadStart是一个委托delegate
Thread构造函数,实际上是创建了一个指向Test()方法的TreadStart委托对象,接着把这个委托对象传给一个新创建的Tread对象的构造函数,
并且调用这个Tread对象的Start()方法来通知CLR:线程已经准备开始执行了。
注意:ThreadStart委托指向一个没有参数,且没有返回值的方法。
2.Task方法(推荐): 只能无参数无返回值
Task a = new Task(new Action(SayHello));
隐式 异步调用:
BeginInvoke方法,隐式创建线程,第三个参数为调用完后的回调函数,第四个一般为null
action.BeginInvoke(2, "你好",null,null);