前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >事件与委托(一)

事件与委托(一)

作者头像
JusterZhu
发布2022-12-07 19:28:41
4460
发布2022-12-07 19:28:41
举报
文章被收录于专栏:JusterZhu

一、详细内容

(1) 什么是委托(Delegates)?

委托是一个对象,它知道如何调用一个方法。

委托的定义:委托类型定义了委托实例可以调用的那类方法,具体来说,委托类型定义了方法的返回类型和参数。

代码语言:javascript
复制
delegate string Hello(string name);
string Splicing(string name){ return $"hello,{ name }."; }

(2) 委托实例

  • 把方法赋值给委托变量的时候就创建了委托实例。
    1. Hello hello = Splicing;
  • 调用
    1. string resultName = hello("bob");//输出 hello bob
  • 委托的实例其实就是调用者的委托:调用者调用委托,然后委托调用目标方法。
  • 间接的把调用者和目标方法解耦合了。
  • 方法是在运行时才赋值给委托变量的。

(3) 多播委托

所有的委托实例都具有多播的能力。一个委托实例可以引用一组目标方法。

引用一组方法的示例:

  • +和+= 还有 -和-=操作符号可以合并和解除委托实例。 DemoDelegate dd = DemoMethond1; DemoDelegate dd += DemoMethond2;
  • 调用委托dd就会调用DemoMethond1和DemoMethond2
  • 委托的调用顺序与他们的定义顺序一致
    • 和 -=会把右边的委托从左边的委托里移除
    1. DemoDelegate dd -= DemoMethond1;
  • 委托变量使用+或+=操作符时,其操作数可以是null。就相当于把一个新的值赋给了委托变量。 DemoDelegate dd = null; dd += DemoMethond1;

相当于

代码语言:javascript
复制
dd = DemoMethond1;
  • 对单个目标方法的委托变量使用-=操作符时,就相当于把null值赋值给了委托变量。
  • 委托是不可变的
  • 使用-=或+=操作符时,实际上是创建了新的委托实例,并把它赋给当前的委托变量。
  • 如果多播委托的返回值不是void,那么调用者从最后一个被调用的方法来接收返回值。前面的方法仍然会被调用,但是其返回值就被弃用了。
  • 所有的委托类型都派生于system.MulticastDelegate,而它又派生于system.delegate
  • c#会把作用于委托的+、-、-=、+=操作编译成使用system.delegate的combine和remove两个静态方法。

实例方法目标和静态方法目标

  • 当一个实例方法被赋值给委托对象的时候,这个委托对象不仅要保留着对方法的引用,还要保留着方法所属实例的引用。
  • system.delegate的Target属性就代表着这个实例。
  • 如果引用的是静态方法,那么Target属性值就是null。
代码语言:javascript
复制
public
delegate
void
Reporter
(
int
result
);



public
class
A

{

public
void
AReporter
(
int
result
)

{

Console
.
WriteLine
(
result
);

}

}



public
class
Program

{

static
void
Main
()

{

A a
=
new
A
();

Reporter
r
=
x
.
AReporter
;

r
(
50
);

Console
.
WriteLine
(
r
.
Target
==
x
);
//True

Console
.
WriteLine
(
p
.
Method
);
//void AReporter(Int32)

}

}

(4) 泛型委托

  • 委托类型可以包含泛型类型
    1. public delegate T Mydelegate<T>(T parameter);

Func和Action委托

  • 使用泛型委托,他们可以调用的方法可以拥有任意返回值类型和任意合理数量的参数。
    1. //1.这里表示的是,只有一个带泛型T返回值类型的委托
    2. delegate TResult Func<out TResult>();
    3. //2.这里表示的是,有一个带泛型T返回值类型和一个带泛型入参的委托(入参数量最多16个)
    4. delegate TResult Func<in T,out TResult>(T parameter);
    5. //3.这里表示的是,一个无参无返回值类型的委托
    6. delegate void Action();
    7. //4.这里表示的是,一个入参无返回值类型的委托(入参数量最多16个)
    8. delegate TResult Func<in T,out TResult>(T parameter);

(5) 委托and接口

  • 委托可以解决的问题,接口都可以解决。
  • 什么情况下更适合委托而不是接口呢?当下列条件满足其中之一时:
    • 接口只能定义一个方法
    • 需要多播能力
    • 订阅者需要多次实现接口
    • <
    1. class A : ICalculation
    2. {
    3. public int Calculation(int x)=> x*x;
    4. }
    5. class B : ICalculation
    6. {
    7. public int Calculation(int x)=> x*x*x;
    8. }

(6) 委托的兼容性

  • 委托类型之间互不相容,即使方法签名一样
    1. delegate void Demo1();
    2. delegate void Demo2();
    3. Demo1 d1 = Method1;
    4. Demo2 d2 = d1;// error
  • 如果委托实例拥有相同的方法目标,那么委托实例就认为是相等的。
  • 当你调用一个方法时,你提供的参数(argument)可以比方法的参数(parameter)定义更具体。
  • 委托可以接受比她的方法目标更具体的参数类型,这个叫ContraVariance
  • 和泛型参类型一样,委托的Variance仅支持引用转换
    1. delegate void StringAction(string s);
    2. class Demo
    3. {
    4. static void Main()
    5. {
    6. StringAction sa = new StringAction(ActOnObject);
    7. sa("hello");
    8. }
    9. static void ActOnObject(object o)=>Console.WriteLine(o);//hello
    10. }
  • 调用方法时,你可以得到一个比请求的类型更具体的类型返回结果。
  • 委托的目标方法可以返回比委托描述里更具体的类型的返回结果Covariance.
  • Covariance,out; ContraVariance,in;
    1. delegate object ObjectRetriever(string s);
    2. class Demo
    3. {
    4. static void Main()
    5. {
    6. ObjectRetriever o = new ObjectRetriever(RetrieverString);
    7. object result = o();
    8. Console.WriteLine(result);
    9. }
    10. static string RetrieverString()=>"hello";
    11. }
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-06-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 JusterZhu 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、详细内容
    • (1) 什么是委托(Delegates)?
      • (2) 委托实例
        • (3) 多播委托
          • (4) 泛型委托
            • (5) 委托and接口
              • (6) 委托的兼容性
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档