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); 

posted @ 2021-06-10 21:04  遥月  阅读(143)  评论(0编辑  收藏  举报