委托定义:委托是一种数据类型,像类一样(可以声明委托类型变量,其实委托还是一个类)
委托的使用
关键字:delegate 声明方式:delegate 返回值类型 委托类型名(参数)
eg:delegate void StringProcess(String s) , StringProcess在这里是委托类型名
将委托类型变量指向函数StringProcess sp=new StringProcess(SayHi),这样就可以像调用普通函数一样把sp当成函数用了。委托可以看成是函数的指针。函数也可以用委托变量指向它。和直接调用函数的区别:用委托就可以指向任意的函数。
委托类型变量的简化写法:StringProcss sp=SayHi。编译器会帮助我们进行new。
Demo1:
Class1.cs
namespace ChangeStringLib { public delegate string ChgStrDelegate(string msg);
public class Class1 { public void ChangeString(string[] str, ChgStrDelegate ChgStr) { //要把字符串数组str中的每个字符串都变成大写。 for (int i = 0; i < str.Length; i++) { //委托,只是把方法中变的地方提取出来。便于写出通用的代码。 str[i] = ChgStr(str[i]); } } } }
Program.cs
namespace TestChangeStringLib { class Program { static void Main(string[] args) { Class1 c1 = new Class1(); string[] names = { "Bob", "Chris", "James", "Steve", "Jhoney" };
//把字符串都变成大写 c1.ChangeString(names, ChangeStringToUpper);
//把字符串的两端都加一个★ c1.ChangeString(names, ChangeStringAddWjx);
foreach (string item in names) { Console.WriteLine(item); } Console.WriteLine("ok"); Console.ReadKey(); }
static string ChangeStringAddWjx(string msg) { return "★" + msg + "★"; }
static string ChangeStringToUpper(string msg) { return msg.ToUpper(); } }
}
匿名方法:
ProcessWordDelegate p=delegate(String s)
{
Console.WriteLine(s);
}
lambda表达式:
lambda-expression 形式的匿名函数的参数可以显式或隐式类型化。在显式类型化参数列表中,每个参数的类型是显式声明的。在隐式类型化参数列表中,参数的类型是从匿名函数出现的上下文中推断的,具体而言,当匿名函数转换为兼容委托类型或表达式树类型时,该类型提供参数类型。
在具有一个隐式类型化参数的匿名函数中,参数列表中可以省略括号。换言之,具有以下形式的匿名函数
( param ) => expr
可以简写为
param => expr
anonymous-method-expression 形式的匿名函数的参数列表是可选的。如果提供了参数,则参数必须显式类型化。如果未给出参数,则匿名函数可以转换为带有不含 out 参数的参数列表的委托。
下面是一些匿名函数示例:
x => x + 1 // Implicitly typed, expression body
x => { return x + 1; } // Implicitly typed, statement body
(int x) => x + 1 // Explicitly typed, expression body
(int x) => { return x + 1; } // Explicitly typed, statement body
(x, y) => x * y // Multiple parameters
() => Console.WriteLine() // No parameters
delegate (int x) { return x + 1; } // Anonymous method expression
delegate { return 1 + 1; } // Parameter list omitted
lambda-expression 和 anonymous-method-expression 的行为除以下几点外是相同的:
anonymous-method-expression 允许完全省略参数列表,从而可转换为具有任意值参数列表的委托类型。
lambda-expression 允许省略和推断参数类型,而 anonymous-method-expression 要求显式声明参数类型。
lambda-expression 的主体可以为表达式或语句块,而 anonymous-method-expression 的主体必须为语句块。
因为只有 lambda-expression 可以具有 expression 主体,所以 anonymous-method-expression 不能成功转换为表达式树类型。
多播委托(委托链,委托的组合)
delegate void ProcessWordDelegate(string s)
ProcessWordDelegate d = new ProcessWordDelegate(SayHello)+new ProcessWordDelegate(ToLower)
组合的委托必须是同一个类型
相当于创建了一个按照组合的顺序依次调用的新委托对象。
委托的组合一般是给事件用的,用普通的委托的时候很少用
为委托的增减方法:
d+=SayHello
d-=SayHello
委托的不可变性:
委托具有类似于string一样的不可变性
建议使用的时候尽量少定义自己的委托,使用系统中已经有的委托。减少程序集中定义的类型的个数。
委托原理
其实就是一个类把方法包装了一下,委托都继承自System.MulticastDelegate,而System.MulticastDelegate又继承自System.Delegate
多播委托就是有一个委托数组,依次调用。
委托类( System.MulticastDelegate )的3个重要成员
_methodPtr、_target来自Delegate类。
_invocationList来自MulticastDelegate类。//实际上是一个Delegate[]类型
internal IntPtr _methodPtr; //
internal object _target; //
private object _invocationList;
委托和内存图
多播原理
写作说明:我是一个菜鸟c#程序员,今天我看传智播客的视频,想总结一下委托,以上的内容是整理的视频上ppt的内容。