C# 委托和事件

1、是什么编程

1)委托包含对方法而不是方法名称的引用。使用委托能够在运行时动态设定要调用的方法,不知道方法名称,也能够调用方法,执行(或调用)一个委托将执行该委托引用的方法。ide

2)委托将名称与方法的定义链接起来,即将方法的实现附加到该名称。这样即可以使用该名称调用特定的方法。可是,委托要求方法的实现和委托必须具备相同的方法签名(也就是说,他们应该具备相同数量/类型的参数),并有相同类型的返回值。函数

3)委托更像一个具备通用的方法名称,在不一样的状况将该名称指向不一样的方法,并经过委托执行这些方法。this

2、怎么用spa

使用委托包括三个步骤:.net

1)定义委托线程

2)实例化委托指针

3)使用委托code

咱们上一个例子:orm

class Program  
{  
    //定义一个委托  
    public delegate int Call(int num1, int num2);  
  
    class Math  
    {  
        public int Mutiply(int num1, int num2)  
        {  
            return num1 * num2;  
        }  
  
        public int Divide(int num1, int num2)  
        {  
            return num1 / num2;  
        }  
    }  
  
    static void Main(string[] args)  
    {  
        Call objCall;  
        Math objMath = new Math();  
        objCall = new Call(objMath.Mutiply);//实例化一个委托  
        
        int result = objCall(5, 3);//使用委托  
        Console.WriteLine("结果为 {0}", result);  
    }  
}  

值得说明是,

objCall = new Call(objMath.Mutiply);//实例化一个委托  

objCall = objMath.Mutiply; //直接给委托赋值

这两种方式效果是同样的,只是两种不一样的写法。用.net reflector反编译上述代码,会发现其实objCall = objMath.Mutiply最终仍是会编译生成objCall = new Call(objMath.Mutiply)。

 上面的例子,咱们再进一步,用匿名委托实现:

static void Main(string[] args)  
{  
    Call objCall = delegate(int num1, int num2) { return num1 * num2; };//匿名委托  
    int result = objCall.Invoke(3, 5);//使用委托  
    Console.WriteLine("结果为 {0}", result);//输出:结果为 15  
}  

咱们还能够将:

int result = objCall.Invoke(3, 5);//使用委托  

替换为:

int result = objCall(3, 5);//使用委托  

效果是同样的。

 再进一步,用Lambda表达式进行简化,能够将:

Call objCall = delegate(int num1, int num2) { return num1 * num2; };//匿名委托  

替换为:

Call objCall = (int num1, int num2) => { return num1 * num2; };//Lambda表达式  

更简化一步,变为:

Call objCall = (num1, num2) => { return num1 * num2; };//Lambda表达式  

这就是C#委托的进化过程以及C#Lambda表达式对委托的支持。

 3、何时用

1)委托相似于C语言中的函数指针,能够将方法做为函数的参数进行传递

2)当不知道方法的具体实现时,就能够定义个委托,让它替咱们干活

3)咱们在编程时用的最多的就是事件注册时使用。

好比:

this.button1.Click += new EventHandler(button1_Click);//button1注册Click事件 
private void button1_Click(object sender, EventArgs e)  
{  
    //方法具体实现内容  
}  

能够看到方法button1_Click做为参数传递给了EventHandler委托。

再好比在线程方法中:

Thread th = new Thread(new ThreadStart(Method));//这里的ThreadStart就是一个委托,里面能够直接传一个方法名Method,以委托的形式调用方法  
th.IsBackground = true;  
th.Start();  

 4、典型应用

好比两个窗体Form1(一个文本框,一个按钮)、Form2(一个文本框,一个按钮)之间进行传值,Form1到Form2能够经过构造函数传值,但若是要将Form2的值传回给Form1该怎么办呢?这里就能够用到委托,这也是委托的经典应用场景之一。

 Form1.cs部分代码:

 private void button1_Click(object sender, EventArgs e)
 {
     Form2 form2 = new Form2();
     //经过public变量传值
     form2.text = this.textBox1.Text;
     //经过委托将子窗体的值传回主窗体
     form2.delegateShow = form2_ShowDelegateEventHandler;
     //经过注册事件将子窗体的值传回主窗体
     form2.ShowDelegateEventHandler += new Form2.ShowDelegate(form2_ShowDelegateEventHandler);
     form2.Show();
 }

 void form2_ShowDelegateEventHandler(string text)
 {
     this.textBox1.Text = text;
 }

 Form2.cs部分代码:

public delegate void ShowDelegate(string text);//声明委托
public event ShowDelegate ShowDelegateEventHandler;//声明事件

public string text;//public变量
public ShowDelegate delegateShow;//public委托变量

private void Form2_Load(object sender, EventArgs e)
{
    this.textBox1.Text = text;
}

private void button1_Click(object sender, EventArgs e)
{
    //写法1:用事件
    if (ShowDelegateEventHandler != null)
        ShowDelegateEventHandler(this.textBox1.Text);

    //写法2:用委托
    delegateShow(this.textBox1.Text);
    this.Close();
}

 5、总结

1)委托是方法的签名,能够将委托做为方法的参数进行传递

2)事件基于委托,或者说事件是特殊的委托

3)委托能够用匿名委托简化代码(不须要再声明委托,而后实现),还能够用Lambda表达式进一步简化匿名委托(这也是C#推荐的方式)。

 

代码下载:https://files.cnblogs.com/files/guwei4037/委托和事件窗体传值.zip

相关文章
相关标签/搜索