目录
一、委托概念
1、使用委托可以提高代码的可扩展性
最优秀的项目是我写过的代码基本上不需要动,如果我需要追加新功能的话,只需要写新功能就可以了,原来的老功能
不需要动一行代码。 有优秀的可扩展性
2、委托的关键字 delegate
Greeting 怎么用委托来实现呢?
二、委托语法规范:
[访问修饰符] delegate 返回值 委托名称(参数1,参数2,参数3,...);
1、声明一个委托
public delegate void TestMuDelegte(string s); //声明一个委托
2、实例化一个委托
TestMuDelegte tes=new TestMuDelegte(方法名);
实例化委托的时候,需要将符合委托定义的方法当做参数传给委托,在该例中,应该传递一个返回值为void,参数
为string的方法名称。
委托是一个类型
3、调用委托
tes("....");
4、把委托当做参数传入方法,调用该方法
public static void GreetNew(string name, GreetDelegate getDel)
{
getDel(name);
}
GreetNew("黄渤", ShandongGreet);
eg:委托实现Greeting:
class Program
{
//1、声明委托:委托中 返回值:void 有一个string类型的参数
public delegate void GreetDelegate(string s);
//把委托当做参数传递
public static void GreetNew(string name, GreetDelegate getDel)
{
getDel(name);
}
static void Main(string[] args)
{
//2、实例化委托对象
GreetDelegate greet = new GreetDelegate(BeijingGreet);
//实例化委托的时候,需要将符合委托定义的方法当做参数传给委托
greet("大张伟");//3、调用委托
GreetNew("黄渤", ShandongGreet);//4、把委托当做参数传入方法,调用该方法
Console.Read();
}
public static void BeijingGreet(string name)
{
Console.WriteLine("你好!"+name);
}
public static void ShandongGreet(string name)
{
Console.WriteLine("你好!" + name);
}
}
//委托简写方式 省略掉new操作符
ComputeDelegate compDel2 = MultyMethod;
Console.WriteLine(compDel2(23, 6));
三、窗体间传值
1、使用静态变量传值
Form1--》Form2传值
1)创建一个类,在该类中创建静态变量,用于存储要传递的值
2)在New Form2对象之前,在Form1的Button点击事件中将文本框中的值存储到静态变量中
3)在Form2的构造函数中,控件初始化方法后,将静态变量中的值赋值给该窗体的文本框
Form2--》Form1传值
1)在Form2中放置一个Button用于关闭该窗体。在上面的类中创建一个静态变量,存储该文本框的值
2)Button的Click事件中,把文本框的值赋值给该静态变量
3)在Form1中,找到New FOrm2的那个Button的Click事件,在SHow()或者SHowDialog()方法下面一行
将存储到静态变量中的值赋值给该窗体的文本框
eg:使用静态变量和构造函数传值
Common类:
class Common
{
public static string UserName;
public static string song;
}
Form1:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
//为静态变量赋值
Common.UserName = textBox1.Text.Trim();
Form2 frm = new Form2();
frm.ShowDialog();
//为Form1中的控件赋值
textBox1.Text = Common.song;
}
/// <summary>
/// 打开FOrm3
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button2_Click(object sender, EventArgs e)
{
Form3 frm = new Form3(textBox1.Text);
frm.ShowDialog();
}
}
Form2:
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
//为控件赋值
textBox1.Text = Common.UserName;
}
private void button1_Click(object sender, EventArgs e)
{
//将文本框中的值保存都公共变量中
Common.song = textBox1.Text;
this.Close();
}
}
Form3:
public partial class Form3 : Form
{
public Form3()
{
InitializeComponent();
}
public Form3(string str):this()
{
textBox1.Text = str;
}
}
2、使用委托的方式进行传值 Form2--》Form1
1)Form2没有办法直接访问Form1中的控件,但是我们可以通过委托,把Form1中的方法传递给FORM2
2)在Form1中先把方法写好,该方法有一个参数,把这个参数赋值给Form1的文本框
private void GetValue(string str)
{
textBox1.Text = str;
}
3)在Form2中声明一个委托,委托的方法原型与上面的方法保持一致,具体如下:
public delegate void TransValueDelegate(string s);
4)在Form2中定义一个委托变量
TransValueDelegate _del;
5)在Form2的构造函数中,添加一个委托参数,在构造函数方法体内将该委托参数传递给该窗体本身的委托变量
public Form2(string str, TransValueDelegate del)
{
InitializeComponent();
textBox1.Text = str;
_del = del;
}
6)在Form2的Button点击事件中,调用委托变量,将文本框的值传入
_del(textBox1.Text);
7)在Form1中,实力化Form2对象的时候,把方法作为参数传递进来
private void button1_Click(object sender, EventArgs e)
{
Form2 frm = new Form2(textBox1.Text, GetValue);
frm.ShowDialog();
}
当Form2子窗体关闭以后,下一行代码会跳到哪里?
下一行代码会跳到打开FOrm2对象的那里
eg:使用委托的方式进行传值
form1:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Form2 frm = new Form2(textBox1.Text, GetValue);
frm.ShowDialog();
}
private void GetValue(string str)
{
textBox1.Text = str;
}
}
form2:
public partial class Form2 : Form
{
public delegate void TransValueDelegate(string s);
TransValueDelegate _del;
public Form2(string str, TransValueDelegate del)
{
InitializeComponent();
textBox1.Text = str;
_del = del;
}
private void button1_Click(object sender, EventArgs e)
{
//关闭按钮之前,先调用委托方法把值传给Form1
_del(textBox1.Text);
//关闭当前窗体
this.Close();
}
}
四、匿名函数与Lambda表达式
一般我们学习C#的时候,说到匿名函数的时候都会谈到lambda表达式.
其实lambda表达式就是匿名函数更为简洁的一种写法.
通俗点讲,你需要写一个函数,但是懒得给它起名字,而且懒得写那么多封装和类.并且可能就这个地方调用,其他地方几乎不调用这段代码,那么我就可以用这个来搞定.。
1、 匿名方法语法规范:
委托类型名称 委托名 = delegate(参数列表){方法体}
ComputeDelegate compDel3=delegate(int x,int y){return x+y;}
2、Lambda表达式实现步骤:
1、声明一个委托
public delegate int TestDelegate(int a, int b);
2、定义一个委托变量,将Lambda表达式赋值给该变量
TestDelegate test = (a, b) => a + b; //加法
3、调用委托
int n=test(12, 13);
五、系统已经定义好的委托
(1). Action
Action是无返回值的泛型委托。
Action 表示无参,无返回值的委托
Action<int,string> 表示有传入参数int,string无返回值的委托
Action<int,string,bool> 表示有传入参数int,string,bool无返回值的委托
Action<int,int,int,int> 表示有传入4个int型参数,无返回值的委托
Action至少0个参数,至多16个参数,无返回值。
例:
public void Test<T>(Action<T> action,T p)
{
action(p);
}
(2). Func
Func是有返回值的泛型委托
Func<int> 表示无参,返回值为int的委托
Func<object,string,int> 表示传入参数为object, string 返回值为int的委托
Func<object,string,int> 表示传入参数为object, string 返回值为int的委托
Func<T1,T2,,T3,int> 表示传入参数为T1,T2,,T3(泛型)返回值为int的委托
Func至少0个参数,至多16个参数,根据返回值泛型返回。必须有返回值,不可void
例:
public int Test<T1,T2>(Func<T1,T2,int>func,T1 a,T2 b)
{
return func(a, b);
}
(4) .predicate
predicate 是返回bool型的泛型委托
predicate<int> 表示传入参数为int 返回bool的委托
Predicate有且只有一个参数,返回值固定为bool
例:public delegate bool Predicate<T> (T obj)
六、事件
1、如果说委托是一个类型,那么事件就是一个对象!
2、事件的创建必须是借助某个委托类型来完成的!
3、也就是说,委托是事件的类型,事件本身是个对象!!
4、所以,事件也可以看成是一个,受到约束的委托实例(委托对象)。
总结:委托是一个类型,事件是委托类型的对象
//注册事件
this.button1.Click += new System.EventHandler(this.button1_Click)
public delegate void EventHandler( object sender , EventArgs e )//委托的声明
public event EventHandler Click; //利用委托定义事件Click
Click += new System.EventHandler(BtnOpen_Click);//为事件注册方法
练习:设计一个简单的Windows程序,实现以下功能:文本框默认显示提示文字“在此,请输入任意文字!”;
进入该文本框时自动清除提示文字;之后由用户输入字符,每输入一个字符就在标签空间中显示一个字符;
离开该文本框时显示“输入结束,
您输入的文字是:”,并显示所输入的文字,同时,文本框再次显示“在此,请输入任意文字!”。
进入该文本框时:MouseEnter
每输入一个字符就...: TextChanged
离开该文本框时..:MouseLeave