委托
想把要调用的函数定义为一个变化的参数,把要它逐个处理的函数定义为一个参数,我传递哪个参数,它就调用哪个参数
View Code
//1先声明一个委托
delegate string DelMethod(string str);
static void Main(string[] args)
{
string[] strs = { "AAVV", "ChWn", "FFccc", "aaJJ" };
//2定义委托,让委托指向方法
DelMethod del = new DelMethod(ToUpper);
//3调用委托
StringProcess(strs, del);
Console.WriteLine(string.Join("-",strs));
}
static void StringProcess(string[] strs,DelMethod del)
{
for (int i = 0; i < strs.Length; i++)
{
strs[i] = del(strs[i]);
}
}
static string ToLower(string str)
{
return str.ToLower();
}
static string ToUpper(string str)
{
return str.ToUpper();
}
让委托指向方法,可以直接这么写DelMethod del = ToUpper;
熟练后就可以 直接使用StringProcess(strs, Toupper);
只要声明一个委托,让它的签名与方法一样,那么把委托作为参数时就可以调用那个方法了;
还可以直接写个匿名方法来使用委托:
DelMethod del = delegate(string str) { return str.ToUpper(); };
第一个例子,我们要比较int数组里最大的数、字符串里最长的数、Person类里年龄最大的数,使用委托来实现:
View Code
class Person
{
public Person() { }
public Person(string name, int age)
{
this.name = name;
this.age = age;
}
private string name;
public string Name
{
get { return name; }
set { name = value; }
}
private int age;
public int Age
{
get { return age; }
set { age = value; }
}
public override string ToString()
{
return name;
}
}
class Program
{
static void Main(string[] args)
{
object[] objInt = {1,2,3,4,5,6,7 };
object[] objString = { "a", "ab", "abc", "abcd" };
object[] objPerson = { new Person("张三", 15), new Person("李四", 21), new Person("老五", 30) };
Console.WriteLine(GetMax(objInt, IntCompare));
Console.WriteLine(GetMax(objString, StringCompare));
Console.WriteLine(GetMax(objPerson, PersonCompare));
Console.ReadKey();
}
delegate int DelMethod(object o1,object o2);
static int PersonCompare(object o1, object o2)
{
Person num1 = (Person)o1;
Person num2 = (Person)o2;
return num1.Age - num2.Age;
}
static int StringCompare(object o1, object o2)
{
string num1 = (string)o1;
string num2 = (string)o2;
return num1.Length - num2.Length;
}
static int IntCompare(object o1, object o2)
{
int num1 = (int)o1;
int num2 = (int)o2;
return num1 - num2;
}
static object GetMax(object[] arr,DelMethod del)
{
object Max=arr[0];
for (int i = 0; i < arr.Length; i++)
{
if (del(Max,arr[i])<0)
{
Max = arr[i];
}
}
return Max;
}
}
第二个例子,跟上面的一样,只是我们是要排序,把他们按从小到大的顺序输出来:
这里是用冒泡算法来排序的
class Person
{
public Person() { }
public Person(string name, int age)
{
this.name = name;
this.age = age;
}
private string name;
public string Name
{
get { return name; }
set { name = value; }
}
private int age;
public int Age
{
get { return age; }
set { age = value; }
}
public override string ToString()
{
return name;
}
}
class Program
{
static void Main(string[] args)
{
object[] objInt = {1,2,3,4,5,6,7 };
object[] objString = { "a", "ab", "abc", "abcd" };
object[] objPerson = { new Person("张三", 15), new Person("李四", 21), new Person("老五", 30) };
Sort(objInt, IntCompare);
Sort(objString, StringCompare);
Sort(objPerson, PersonCompare);
Console.WriteLine(string.Join("-", objInt));
Console.WriteLine(string.Join("-", objString));
Console.WriteLine(string.Join("-", objPerson));
Console.ReadKey();
}
delegate int DelMethod(object o1,object o2);
static int PersonCompare(object o1, object o2)
{
Person num1 = (Person)o1;
Person num2 = (Person)o2;
return num1.Age - num2.Age;
}
static int StringCompare(object o1, object o2)
{
string num1 = (string)o1;
string num2 = (string)o2;
return num1.Length - num2.Length;
}
static int IntCompare(object o1, object o2)
{
int num1 = (int)o1;
int num2 = (int)o2;
return num1 - num2;
}
static void Sort(object[] arr, DelMethod del)
{
bool isChanged = false;
for (int i = 0; i < arr.Length; i++)
{
isChanged = false;
for (int j = 0; j < arr.Length-1-i; j++)
{
if (del(arr[j], arr[j + 1])>0)
{
object item = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = item;
isChanged = true;
}
}
if (!isChanged)
break;
}
}
}
第三个例子,我们使用系统带的排序方法;
系统里带的Sort排序方法,数字是从小到大排序的,字符串是按从a到z排序的;
Sort()方法参数有个委托参数,public delegate int Comparison<in T>(T x, T y);所以我们可以按照它的签名来写一个方法,实现我们想要的排序
Sort方法
class Person { public Person() { } public Person(string name, int age) { this.name = name; this.age = age; } private string name; public string Name { get { return name; } set { name = value; } } private int age; public int Age { get { return age; } set { age = value; } } public override string ToString() { return name; } } class Program { static void Main(string[] args) { List<int> listInt = new List<int>{1,2,3,4,5,6,7 }; List<string> listString = new List<string>() { "d", "ba", "cba", "dcba" }; List<Person> listPerson = new List<Person>() { new Person("张三", 15), new Person("李四", 21), new Person("老五", 30) }; listInt.Sort(); listString.Sort(StringCompare); listPerson.Sort(PersonCompare); Console.WriteLine(string.Join("-", listInt)); Console.WriteLine(string.Join("-", listString)); Console.WriteLine(string.Join("-", listPerson)); Console.ReadKey(); } static int StringCompare(string s1, string s2) { return s1.Length - s2.Length; } static int PersonCompare(Person p1, Person p2) { return p1.Age - p2.Age; } }
可以使用委托实现用户登录控件,让不同的窗体使用时可以实现不同的操作(调用不同的数据库来操作);
委托是一个数据类型,要实例化后才能调用
//1声明委托 public delegate void DelMethod(string userName, string pwd); //2让委托指向方法 public DelMethod del; private void button1_Click(object sender, EventArgs e) { if (string.IsNullOrEmpty(textBox1.Text)) { MessageBox.Show("用户名不能为空"); } else if (string.IsNullOrEmpty(textBox2.Text)) { MessageBox.Show("密码不能为空"); } else { //DelMethod(textBox1.Text, textBox2.Text)这么写不对 if (del != null)//委托指向的方法不为null时; { //3.调用委托 del(textBox1.Text, textBox2.Text); } } }
给委托添加方法
private void Form1_Load(object sender, EventArgs e) { ucLogin1.del = new UCLogin.DelMethod(Login); } static void Login(string user, string pwd) { if (user == "admin" && pwd == "admin") { MessageBox.Show("登陆成功"); } else { MessageBox.Show("用户名密码不正确"); } }
为什么说事件就是委托,可以使用反编译看一下,事件其实就是封装了委托,还有两个方法;跟属性差不多。
使用事件来实现上面的用户登录的例子:
用事件实现
public delegate void DelMethod(string name, string pwd); public event DelMethod del;//定义一个事件 private void button1_Click_1(object sender, EventArgs e) { if (string.IsNullOrEmpty(textBox1.Text)) { MessageBox.Show("用户名不能为空"); return; } else if (string.IsNullOrEmpty(textBox2.Text)) { MessageBox.Show("密码不能为空"); return; } else { if (del != null) { del(textBox1.Text, textBox2.Text); } } }
View Code
private void Form1_Load(object sender, EventArgs e) { //+=后面直接两个Tab键就可以添加事件了 ucLogin1.del += new UCLogin.DelMethod(ucLogin1_del); } void ucLogin1_del(string name, string pwd) { if (name == "admin" && pwd == "admin") { MessageBox.Show("登陆成功"); } else { MessageBox.Show("用户名密码不正确"); } }
View Code
浙公网安备 33010602011771号