.NET Core 委托delegate (一)

摘要:
例如:1.启动线程和任务——基类System的实例。线程。线程调用方法Start()来启动线程。因此。NET框架在语法中不允许此直接方法。委托正在处理方法NET版本。示例2:delegatedoubleTwoLongsOption;定义了委托TwoLongsOption。委托表示的方法有两个长参数,返回类型为double。类程序{privatedelegatestringGetAString();staticvoidMain{intx=40;GetAStringgetAString=newGetAString;Console.WriteLine;}}此代码用new实例化GetAString类型的委托并初始化它。,以下示例是一个示例:1GetAStringgetAString1=x。ToString;GetAString1和getAString具有相同的含义。x、 ToString()返回字符串对象。

1、什么是委托

当需要把方法传递给其他方法时,就需要使用委托。

我们习惯于把数据作为参数传递给方法,而有时某个方法执行的操作并不是针对数据进行的,而是要对另外一个方法进行调用。更麻烦的是,在编译时我们是不知道第二个方法是什么的,这个信息只能在运行时得到,所以需要把第二个方法作为参数传递给第一个方法。例如:

1、启动线程和任务——基类System.Threading.Thread的实例调用方法Start(),就可以启动一个线程。如果告诉计算机启动一个新实例,就必须说明要在哪里启动该序列;必须为计算机提供开始启动的方法和细节,即Thread类的构造函数必须带有一个参数(该参数定义了线程调用的方法)。

2、事件——一般的思路是通知代码发生了什么事件。GUI编程主要处理事件。引发事件时,运行库需要知道应该执行哪个方法。这就需要把处理事件的方法作为参数传递给委托。

c++中,函数指针是一个指向内存地址的指针。但它不是类型安全的(无法判断这个指针实际指向什么,更无从知晓参数和返回类型了),可以把任何函数传递给需要函数指针的方法。这不仅会导致一些类型安全问题,而且没有意识到:在进行面向对象编程时,几乎没有方法时孤立存在的,而是在调用方法前通常需要和类的实例相关联。所以.NET framework在语法上不允许使用这种直接方法。如果要传递方法,就必须把方法的细节封装在一种新的对象类型中,即委托。委托只是一种特殊类型的对象——我们之前定义的所有对象都包含数据,而委托包含的只是一个或多个方法的地址。

委托就是寻址方法的.NET版本。

2、声明委托

一般的,C#中使用一个类,分为两个阶段:1、定义一个类(即告诉编译器这个类由什么字段和方法组成);2、实例化该类的一个对象(除非只使用静态方法)。

使用委托时,也需要这两个步骤:1、定义委托(即告诉编译器这种委托表示哪种类型的方法);2、创建该委托的一个或多个实例(编译器将在后台创建表示这个委托的一个类)

声明委托的示例1:

delegate  void  DelegateNameInvoker(int x);

这个示例中,声明了一个委托DelegateNameInvoker,它指定该委托的每个示例都可以包含一个方法的引用,该方法带有一个int参数,并返回void。定义委托时,必须给出它所表示的方法的签名和返回类型等全部细节(类型安全)理解委托的一个好方式是把委托视为给方法的签名和返回类型指定名称。

示例2:

delegate  double TwoLongsOption(long first , long second);

定义了一个委托TwoLongsOption,该委托表示的方法有两个long参数,返回类型是double。

3、使用委托

定义好委托后,就可以创建它的一个实例,从而用该实例存储特定方法的细节。

下面的代码说明了如何调用委托:这是一个在int值上调用ToString()方法的一个相当冗长的方式。

    class Program
    {
        private delegate string GetAString();
        static void Main(string[] args)
        {
            int x = 40;
            GetAString getAString = new GetAString(x.ToString);
            Console.WriteLine(getAString());
        }
    }

这段代码,用new实例化了类型为GetAString的委托,并对它进行初始化(引用整形变量x的ToString()方法)。委托在语法上总是接受一个参数的构造函数,这个参数就是委托引用的方法,且这个方法必须匹配委托的签名。

实际上,给委托实例提供圆括号与调用委托类的Invoke()方法完全相同。

委托推断:为了减少输入量,在需要委托实例(即new的时候)的每个位置可以只传送地址的名称。,下面的例子就是一个例子:

1 GetAString getAString1 = x.ToString;

getAString1和getAString表示相同的含义。

注意:输入形式不能为x.ToString()。x.ToString()会返回一个字符串对象。只能把方法的地址赋予给委托。

委托是类型安全的,但有趣的是,它不关心在什么类型的对象上调用该方法,甚至不考虑方法时静态方法还是实例方法(只要方法的签名匹配委托的签名即可)。

下面的代码,扩展了上面的例子,委托getAString在另外一个对象上调用其他2个方法,一个是实例方法,一个静态方法:

 1         struct Currency
 2         {
 3             public uint Dollars;
 4             public ushort Cents;
 5             public Currency(uint dollars,ushort cents)
 6             {
 7                 Dollars = dollars;
 8                 Cents = cents;
 9             }
10             //实例方法
11             public override string ToString()
12             {
13                 return $"{Dollars}.{Cents}";
14             }
15             //GetCurrencyUint是一个静态方法
16             public static string GetCurrencyUint() => "Dollar";
17         }
18         private delegate string GetAString();
19         static void Main(string[] args)
20         {
21             int x = 40;
22             GetAString getAString = new GetAString(x.ToString);
23             Console.WriteLine(getAString());
24 
25             var currency = new Currency(22, 11);
26             //调用实例方法
27             getAString = currency.ToString;
28             Console.WriteLine(getAString());
29             //调用类的静态方法
30             getAString = Currency.GetCurrencyUint;
31             Console.WriteLine(getAString());
32 
33         }

4、简单的委托示例

下面的代码描述了委托的其中一个小用途——把方法组合到一个数组中,这样就可以在循环中调用不同的方法了:

 1         class MathOperations
 2         {
 3             public static double MultiplyBy2(double value) => value * 2;
 4             public static double Square(double value) => value * value;
 5         }
 6         delegate double DoubleOp(double x);
 7         static void Main(string[] args)
 8         {
 9             DoubleOp[] doubleOps =
10             {
11                 MathOperations.MultiplyBy2,
12                 MathOperations.Square
13             };
14             
15             for(int i = 0; i < doubleOps.Length; i++)
16             {
17                 Console.WriteLine($"调用方法{i}:");
18                 ProcessDisplay(doubleOps[i], 2.0);
19                 ProcessDisplay(doubleOps[i], 2.2);
20             }
21 
22         }
23 
24         private static void ProcessDisplay(DoubleOp doubleOp, double v)
25         {
26             Console.WriteLine($"变量是:{v},结果是:{doubleOp(v)}");
27         }

运行结果:

.NET Core 委托delegate (一)第1张

免责声明:文章转载自《.NET Core 委托delegate (一)》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇jQueryEasyUI Messager基本使用谈lisp下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

协议(Protocol) 和代理(Delegate)

1、概念与组成 delegate是iOS中一种常见的设计模式,是一种消息传递的的方式,常见的消息传递方式还有以下几种: 通知:在iOS中由通知中心进行消息接收和消息广播,是一种一对多的消息传递方式。 代理:是一种通用的设计模式,iOS中对代理支持的很好,由代理对象、委托者、协议三部分组成。 block:iOS4.0中引入的一种回调方法,可以将回调处理代...

Unity3D游戏轻量级xlua热修复框架

一  这是什么东西 前阵子刚刚集成xlua到项目,目的只有一个:对线上游戏C#逻辑有Bug的地方执行修复,通过考察xlua和tolua,最终选择了xlua,很大部分原因是因为项目已经到了后期,线上版本迭代了好几次,所以引入Lua的目的不是为了开发新版本模块。xlua在我们的这种情况下很是适用,如xlua作者所说,用C#开发,用lua热更,xlua这套框架为...

iOS设计模式——委托(delegate)

委托(delegate)也叫代理是iOS开发中常用的设计模式。我们借助于protocol(参考博文:objective-c协议(protocol))可以很方便的实现这种设计模式。 什么是代理? 苹果的官方文档给了很清晰的解释: Delegation is a simple and powerful pattern in which one object...

MyBatis 物理分页

MyBatis使用RowBounds实现的分页是逻辑分页,也就是先把数据记录全部查询出来,然在再根据offset和limit截断记录返回 为了在数据库层面上实现物理分页,又不改变原来MyBatis的函数逻辑,可以编写plugin截获MyBatis Executor的statementhandler,重写SQL来执行查询 参考资料: http://blog....

iOS- 微信支付 (服务器调起支付 )以及回调不成功的原因 不看后悔

写的不错,给留个言哈... 一. 支付准备工作 1. 微信相关准备工作 (1) 向微信官方开通支付功能. 这个不是前端的工作. (2) 导入官方下载的微信支付SDK包. 我用的是微信开放平台下载的SDK 1.6.2 (3) 导入必要的库文件 SystemConfiguration.framework, libz.dylib, libsqlite3.0.d...

C# 委托及各种写法

委托是嘛? 委托是一个类型安全的对象,它指向程序中另一个以后会被调用的方法(或多个方法)。通俗的说,委托是一个可以引用方法的对象,当创建一个委托,也就创建一个引用方法的对象,进而就可以调用那个方法,即委托可以调用它所指的方法。 如何使用委托? 1、定义委托类型 [访问修饰符]delegate 返回类型 委托名(形参); 2、声明委托对象 委托名 委托实例...