澳门在线威尼斯官方 > 澳门在线威尼斯官方 > 架构的血液

原标题:架构的血液

浏览次数:161 时间:2019-09-13

这里我们会发现,委托的使用方式与函数调用一样。

有了引用函数的委托变量之后,我们就可以用委托变量调用Muiltiply函数;也可以把委托变量传递给其他函数

如果需要公共委托,可以采取反射的方式来调用。

其中Action是无返回值的泛型委托,Func是有返回值的泛型委托,Predicate<>是返回bool类型的委托,他们都有多个参数的重载版本

本篇文章主要介绍委托的应用。

还可以用另一种略微简单的语法

重要的话要讲三遍。

  1. 使用委托

Action与Func

Action<>,Func<>,Predicate<> 其实他们都是委托代理的简写形式,通过他们可以省去定义委托的步骤

委托是大家最常见的语法了,但会用与精通之间的差别是巨大的。

匿名委托使用起来更简洁一点,不用在定义一个专用的委托函数来传递方法,也更可以更好的理解委托

所以,委托是架构的血液,是框架的流畅的基石。

  • 委托可以调用多个方法,即一个委托变量可以引用多个函数,称为多路广播
  • 可以使用+=和-=运算符实现方法的增加和减少
  • 无返回值的委托,引用了多少个方法就会执行多少个方法。有返回值的委托同样会执行多个引用的方法,但返回的值是最后一个方法的返回值

那就是——引用类型的函数。

定义了委托后,就可以声明一个该委托类型的变量

学会了赋值以后,我开始使用委托。

 

Action<int> a1 = (i) =>  { };
Func<string,int> f1 = (str) => {  return 1;//必须写 return 1; };
delegate double ParocessDelegate(double param1,double param2);

世界上本没有回调函数,叫的人多了,也就有了。

 

很简单,我们把delegate后面的 【void TestDelegate(string message)】理解为一个变量,是不是就清晰明了了一些。

初始化委托变量时要把一个函数(此处Multiply为一个函数的名称)引用赋给委托变量,此函数需要具有与委托相同的返回类型和参数列表。c#使用上述略显古怪的语法,使用new关键字创建一个新的委托,参数为
要引用所需的函数,这是委托赋值的一个独特语法,函数名称是不带括号的

这个应用,是最常见,也最普通的应用了。因为委托是引用类型,所以A类里定义的委托,可以在被内存回收之前,被其他类调用。

示例

public delegate void TestDelegate(string message);
public delegate long TestDelegate2(int m, long num);
public static void Excute()
{
    TestDelegate2 td = Double; 
} 
static long Double(int m, long num)
{
    return m * num;
}
process (param1,param2);

C#语法——元组类型

process = Muiltiply;

public delegate int DelegateProcess(int num1, int num2);

//第一种写法
DelegateProcess process= new DelegateProcess(Multiply);

//第二种写法
DelegateProcess process= Multiply;

//第三种写法  匿名委托
DelegateProcess process= delegate(int a,int b)
{
   return a*b;
}

//第四种写法 Lamdba表达式
DelegateProcess process =((int a,int b)=>{return a*b;});

//第五种写法 Action<T>和Func<T>
Action<int,int> process= ((int a,int b)=>{Console.WriteLine(a * b);});
Func<int,int,int> process= ((int a,int b)=>{return a*b;});

这样,你才能称为[Developer]。

ProcessDelegate process;

委托实际上是一种类型,是一种引用类型。

  //定义委托
    delegate string lookMe(string s);

    protected void LinkButton1_Click(object sender, EventArgs e)
    {
        //匿名委托
        lookMe lm = delegate(string name) { return "亲爱的 " + name + ",请看着我的眼睛!"; };

        //匿名委托调用
        string name1 = "jarod";
        Label1.Text = lm(name1);
    }

答案当然是,可以的。

澳门在线威尼斯官方 ,  2.  其他形式的委托

委托,架构的血液

 

委托的定义

 

class ChildDelegateSyntax : BaseDelegateSyntax
{
    public void Excute()
    {
        //开启异步方法
        base.AsyncLoad(() => { });

        //开启异步方法,并且在异步结束后,触发回调方法
        base.AsyncLoad(() => { },
            ()=> 
            {
                //我是回调方法
            });

        //开启异步有入参的方法,传递参数,并且在异步结束后,触发回调方法
        base.AsyncLoad<string>((s) => { },"Kiba518",
           () =>
           {
                //我是回调方法
           });

        //开启异步有入参的方法,传递字符串参数Kiba518,之后返回int型结果518,
        //并且在异步结束后,触发回调方法,回调函数中可以获得结果518
        base.AsyncLoad<string,int>((s) => {
            return 518;
        }, "Kiba518",
           (result) =>
           {
               //我是回调方法 result是返回值518
           });
    }
}
public static void HellowChinese(string strChinese)  
{  
    Console.WriteLine("Good morning," + strChinese);  
    Console.ReadLine();  
}  

Action<string> action = HellowChinese;  
action("Spring.");  

运行结果如下:

  • 匿名委托

比如可以跨类调用,跨程序集调用等等。而这种用法,就是委托的基本应用。

委托是一种存储函数引用的类型,在事件和事件的处理时有重要的用途

public class FirstDelegateSyntax
{
    public FirstDelegateSyntax()
    {
        Console.WriteLine(" First 开始 "  );
        SecondDelegateSyntax sds = new SecondDelegateSyntax(()=> {
            Console.WriteLine(" First传给Second委托被触发 ");
        });
        sds.Excute();
        Console.WriteLine(" First 结束 ");
    }
}

public class SecondDelegateSyntax
{
    public Action Action { get; set; }
    public SecondDelegateSyntax(Action _action)
    {
        Console.WriteLine(" Second的构造函数 ");
        Action = _action;
    }
    public void Excute()
    {
        Console.WriteLine(" Second的Excute被触发 ");
        Action();
    }
}

 

下面先看下声明代码,这里声明了两个委托。

声明委托类型的变量

就好比一碗汤面倒掉了所有的汤,只要它静放一个阵子,就会变成一坨面球,让你无从下嘴。

 

接下来,我们来看委托的第二种核心用法,穿越的应用。

  • 泛型委托

也就是说,我们可以不用再去自己手动声明委托了。

委托的使用需要以下步骤:

子类代码如下:

 

但委托这种列车,是每个程序员都可以定义的,如果一个项目中有十个开发者,每个人都在定义委托,那么,就有可能出现定义了十个相同的委托的情况,这样就出现了撞车的现象。

   3.  委托的各种写法

有没有感觉,这个复杂的变量特别像一个函数的定义。

process =new ProcessDelegate(Multiply);

结语

namespace Delegate
{

        public delegate int Call(int num1, int num2);//第一步:定义委托类型
        class SimpleMath
        {
            // 乘法方法
            public int Multiply(int num1, int num2)
            {
                return num1 * num2;
            }

            // 除法方法
            public int Divide(int num1, int num2)
            {
                return num1 / num2;
            }
        }
    }
    class Test
    {
        static void Main(string[] args)
        {
            Call objCall;//第二步:声明委托变量
            // Math 类的对象
            SimpleMath objMath = new SimpleMath(); 
            // 第三步:初始化委托变量,将方法与委托关联起来
            objCall = new Call(objMath.Multiply);


            objCall += objMath.Divide;//向委托增加一个方法
            //objCall -=  objMath.Divide;//向委托减去一个方法

            // 调用委托实例,先执行objMath.Multiply,然后执行objMath.Divide
            int result = objCall(5, 3);
            System.Console.WriteLine("结果为 {0}", result);
            Console.ReadKey();
        }
    }

匿名委托的应用

 

我们能看到两种委托应用,代码都非常简洁。

注意事项:

class BaseDelegateSyntax
{ 
    public void AsyncLoad(Action action)
    {

    }
    public void AsyncLoad(Action action, Action callback)
    {
        IAsyncResult result = action.BeginInvoke((iar) =>
        {
            callback();
        }, null);
    }
    public void AsyncLoad<T>(Action<T> action, T para, Action callback)
    {
        IAsyncResult result = action.BeginInvoke(para, (iar) =>
        {
            callback();
        }, null);
    }
    public void AsyncLoad<T, R>(Func<T, R> action, T para, Action<R> callback)
    {
        IAsyncResult result = action.BeginInvoke(para, (iar) =>
        {
            var res = action.EndInvoke(iar);
            callback(res);
        }, null);
    }
}

委托的定义非常类似于函数,但不带函数体,且要使用delegate关键字。委托定义需要指明委托名称以及一个返回类型和一个参数列表

委托是架构的血液,如果系统中没有委托,那代码将堆叠到一起,比大力胶粘的都紧密。

通俗的说,委托是一个可以引用方法的类型,当创建一个委托,也就创建一个引用方法的变量,进而就可以调用那个方法,即委托可以调用它所指的方法。

没错,它们的确是一样的。因为委托是用函数来赋值的,所以调用方式一样也并不奇怪,不是吗。

 

Action action = new Action(() => { });
IAsyncResult result = action.BeginInvoke((iar) =>
{
}, null);

Func<int> func = new Func<int>(() => { return 1; });  
IAsyncResult resultfunc = func.BeginInvoke((iar) =>
{
    var res = func.EndInvoke(iar); 
}, null);

 

我们可以在列车上放很多很多东西,在需要的站点,叫停列车,并将托运的东西搬下来使用。

初始化委托变量

第二核心应用——穿越你的世界:

示例:

因为委托是引用类型,所以可以被[址传递]。函数是不可以被传递的。

定义委托

注:此文章为原创,欢迎转载,请在文章页面明显位置给出此文链接!
若您觉得这篇文章还不错,请点击下右下角的【推荐】,非常感谢!
如果您觉得这篇文章对您有所帮助,那就不妨支付宝小小打赏一下吧。 

 

Action与Func是泛型委托,各支持16个入参变量。下面代码为一个入参的定义,多参数以此类推。

首先,我们创建父类代码如下:

那么,为什么这个声明方式如此怪异呢,是因为,我们用delegate定义的变量,只能用函数赋值。赋值方式如下所示:

第三核心应用——回调函数:

下面我们看下穿越应用的代码。

下面我们再来看委托的异步应用。首先看最简单的异步调用。

delegate既然是关键字,和int,string一样,那么,为什么delegate后又跟了一个void或者int呢?

看了上面的父子类后,是否感觉委托让我们繁杂的线程世界变简洁了呢?

本文由澳门在线威尼斯官方发布于澳门在线威尼斯官方,转载请注明出处:架构的血液

关键词:

上一篇:没有了

下一篇:没有了