• delegate使用方法C#(Demo)


    1. 委托实际就是C语言的函数指针。
    2. 2个必须条件:方法类型和参数类型及数量必须一致(类型和数量)。
    3. 局部声明的方法实际是有地址的。
    4. 委托是全局的,
    5. 所以绑定方法地址后,任何地方呼叫委托,实际就是呼叫你绑定的方法。
    6. C语言里有野指针的情况,C#做了优化,不允许null地址和左右值类型不匹配不能绑定。

    老鸟路线

    无返回值:   Control  控件父类

    1. namespace System
    2. {
    3. [__DynamicallyInvokable]
    4. public delegate void Action<in T>(T obj);
    5. }
    6. // 系统默认定义了全局变量的委托,名字叫 Action
    1. // 方法原型,方法参数
    2. textBox1.Invoke(new Action<string>(str => { textBox1.Text = str; }),"str是参数的名字");

     字符串会代入str 

     这是3个参数的无返回值方法

    有返回值

    1. public object Invoke(Delegate method)
    2. {
    3. return Invoke(method, null);
    4. }

    无参有返回 

    1. namespace System
    2. {
    3. [TypeForwardedFrom("System.Core, Version=3.5.0.0, Culture=Neutral, PublicKeyToken=b77a5c561934e089")]
    4. [__DynamicallyInvokable]
    5. public delegate TResult Func<in T, out TResult>(T arg);
    6. }

    < >内是类型占位符, 最后一个是返回值的类型。 只有1个参数时,括号可不写,直接写参数名字,比如 x

    textBox1.Invoke(new Func<string, string>(x => textBox1.Text = x.ToString()),"x是参数名字"); 

     第2个string是返回值的类型。

    新手路线

    问题出在哪:在类A内,新建类B,类A是可以调用B的属性和方法,但是B的方法体内,不能调用A的方法。

    场景:主窗体内新建了子窗体,主窗体可以调用子窗体所有的属性方法。但是子窗体方法内不能调用主窗体的方法》最大化,最小化等等方法。

    切入点:在学C语言的时候,如果函数体main方法后面,那main的前面必须写函数声明。

    C#也是如此。类A 内 using引用了   类B   命名空间,那这个命名空间就相当于全局变量区。(A和B都访问的到) 在类B命名空间下   delegate方法声明

    主窗体是可以访问子窗体属性的,所以把 delegate定义成子窗体的属性(中介)。子窗体当然可以使用自己的属性。子窗体的方法内调用自己的属性。

    主窗体把自己的方法绑定给子窗体的属性(中介)。这样子窗体调用的时候间接的调用主窗体的方法。

    主窗体程序:

    1. using System;
    2. using System.Collections.Generic;
    3. using System.ComponentModel;
    4. using System.Data;
    5. using System.Drawing;
    6. using System.Linq;
    7. using System.Text;
    8. using System.Threading.Tasks;
    9. using System.Windows.Forms;
    10. ///
    11. /// qq750273008,委托测试
    12. ///
    13. namespace delegateTest
    14. {
    15. //【1】第1步:声明委托(公共区)
    16. public delegate void WT子呼叫(string str, string str2);//子窗体用
    17. public delegate void WT主广播(string str ,string str2);// 主窗使用 (加载所有子窗的方法)方便统一管理
    18. //主窗体
    19. public partial class Form1 : Form
    20. {
    21. #region 全局变量
    22. UInt16 fromNum = 1;//子窗体编号
    23. WT主广播 wt主广播;//主窗的.属性(用于加载子窗的方法)
    24. private List
      forms = new List();//子窗集合管理对象
    25. #endregion
    26. #region 窗体构造
    27. public Form1()
    28. {
    29. InitializeComponent();
    30. }
    31. #endregion
    32. #region 钮_创建子窗体
    33. private void btn1_创建子窗体(object sender, EventArgs e)
    34. {//创建子窗体
    35. for (int i = 0; i < 3; i++)//每次创建3个窗口
    36. {
    37. Form2 form子窗 = new Form2("子窗体", $"子窗体:{fromNum++}");
    38. form子窗.Show();
    39. //===========================
    40. //【4】第4步:将委托变量和具体方法关联(使用=和+=是一样的效果)
    41. form子窗.wt子呼叫 += x显示子消息;//子窗体 呼叫 主窗体
    42. //===========================
    43. this.wt主广播 += form子窗.父消息;//调用子窗体方法
    44. forms.Add(form子窗);//加入到集合,方便控制
    45. }
    46. }
    47. #endregion
    48. #region 显示消息
    49. //【2】第2步:根据委托编写具体方法
    50. private void x显示子消息(string str, string str2)
    51. {
    52. string str3 = ("来自" + str + " 的消息:" + str2 + "\r\n");
    53. textBox1.AppendText(str3);
    54. }
    55. #endregion
    56. #region 广播
    57. private void btn4_广播(object sender, EventArgs e)
    58. {
    59. try
    60. {
    61. wt主广播("主广播:", textBox2.Text);//wt广播A
    62. }
    63. catch (Exception ex)
    64. {
    65. MessageBox.Show("没有子窗体,无法发送", "失败");
    66. MessageBox.Show(ex.Message);
    67. // throw;
    68. }
    69. }
    70. #endregion
    71. #region 清空
    72. private void btn2_清空(object sender, EventArgs e)
    73. {
    74. textBox1.Text = string.Empty;
    75. }
    76. #endregion
    77. #region 关闭子窗体
    78. private void btn3_关闭子窗体(object sender, EventArgs e)
    79. {//关闭窗口
    80. foreach (var item in forms)
    81. {
    82. item.Close();
    83. }
    84. fromNum = 1;//子窗体编号复位
    85. }
    86. #endregion
    87. }
    88. }

    子窗体程序:

    1. using System;
    2. using System.Collections.Generic;
    3. using System.ComponentModel;
    4. using System.Data;
    5. using System.Drawing;
    6. using System.Linq;
    7. using System.Text;
    8. using System.Threading.Tasks;
    9. using System.Windows.Forms;
    10. namespace delegateTest
    11. {
    12. //子窗体
    13. public partial class Form2 : Form
    14. {
    15. //【3】第3步:声明委托
    16. public WT子呼叫 wt子呼叫;// 属性
    17. public Form2(string str, string str2)
    18. {
    19. InitializeComponent();
    20. this.Text = str2;
    21. }
    22. public void 父消息(string str,string str2)
    23. {
    24. textBox2_接收框.Text = str + str2;
    25. }
    26. private void btn1发送消息(object sender, EventArgs e)//触发按键
    27. {
    28. //【1】第5步:使用委托变量来调用所关联的方法
    29. //wt("测试", "123");
    30. wt子呼叫(this.Text.ToString(), textBox1_发送框.Text.ToString()); // 子窗编号 + 内容
    31. }
    32. }
    33. }

  • 相关阅读:
    实用干货!看壹哥如何在SpringBoot项目中同时支持https和http协议
    911. 在线选举
    Chinese-LLaMA-AIpaca
    web前端面试高频考点——Vue3.x深入理解(v-model参数用法、watch和watchEffect区别、Vue3快于Vue2、Vite启动快的原因)
    Verilog语法速成2
    创业合伙必读之:合伙企业登记指南
    Python 面试:单元测试unit testing & 使用pytest
    C++异常
    QT c++ 将浮点数数组转换成 QByteArray
    Docker 必知必会2----跟我来一步步执行基本操作
  • 原文地址:https://blog.csdn.net/cfqq1989/article/details/127454315