发文章
发文工具
撰写
网文摘手
文档
视频
思维导图
随笔
相册
原创同步助手
其他工具
图片转文字
文件清理
AI助手
留言交流
先看看委托的概述:
委托类似于 C++ 函数指针,但它们是类型安全的。
委托允许将方法作为参数进行传递。
委托可用于定义回调方法。
委托可以链接在一起;例如,可以对一个事件调用多个方法。
方法不必与委托签名完全匹配。 有关更多信息,请参见 在委托中使用变体(C# 和 Visual Basic)。
C# 2.0 版引入了匿名方法的 概念,此类方法允许将代码块作为参数传递,以代替单独定义的方法。 C# 3.0 引入了 Lambda 表达式,利用它们可以更简练地编写内联代码块。 匿名方法和 Lambda 表达式(在某些上下文中)都可编译为委托类型。 这些功能统称为匿名函数。 有关 lambda 表达式的更多信息,请参见 匿名函数(C# 编程指南)。
委托是一种定义方法签名的类型。 当实例化委托时,您可以将其实例与任何具有兼容签名的方法相关联。 您可以通过委托实例调用方法。
委托用于将方法作为参数传递给其他方法。 事件处理程序就是通过委托调用的方法。 您可以创建一个自定义方法,当发生特定事件时某个类(例如 Windows 控件)就可以调用您的方法。
例子1:
class Program { static void Main(string[] args) { Hello(); } static void Hello() { System.Console.WriteLine("Hello, Delegate!"); } }
这是一个常见的方法, 输出一段字符串Hello, Delegate!
下面我们来把他写成委托,
class Program { delegate void PrintHello(); static void Main(string[] args) { PrintHello ph = new PrintHello(Hello); ph.Invoke(); } static void Hello() { System.Console.WriteLine("Hello, Delegate!"); } }
这里的PrintHello的方法类型需要和Hello保持一直,另外参数也需要保持一致,现在是无参数的.讲Hello作为参数传到委托中,然后用Invoke调用.以上代码也会输出,Hello, Delegate!因为invoke了这个方法.
从.net 2.0开始就使用匿名委托, 可以这样申明
delegate { };
或者带参数的
delegate (string i){ };
{}括号中可以写需要执行的逻辑代码.
有了匿名委托我们就可以偷一下懒了,可以把上面的例子改成如下:
class Program { delegate void PrintHello(); static void Main(string[] args) { PrintHello ph = delegate { System.Console.WriteLine("Hello, Delegate!"); }; ph.Invoke(); } //static void Hello() //{ // System.Console.WriteLine("Hello, Delegate!"); //} }
在.net 3.0中除了Action<T> 无返回的委托, Predicate<T>有返回值,且返回true或false的委托.
我们可以将上面的例子改成有参数的,
class Program { static Action<string> print = delegate(string i) { System.Console.WriteLine("Hello, {0}!",i); }; static void Main(string[] args) { print.Invoke("Delegate"); } }
或者用lambda表达式替代匿名委托,进一步偷懒..
class Program { static Action<string> print = (i)=>{ System.Console.WriteLine("Hello, {0}!",i); }; static void Main(string[] args) { print.Invoke("Delegate"); } }
以上会输出Hello,Delegate!因为将Delegate传入到最后输出.
再来讲解一下Predicate这个只返回true or false的委托,如下:
class Program { static Predicate<string> print = (i) => { return string.IsNullOrEmpty(i); }; static void Main(string[] args) { System.Console.WriteLine(print.Invoke("Hello, Delegate!")); } }
以上代码会输入true因为i不是为null or empty.
在.net 3.5中又新加了Action(无返回值的委托,类似于delegate void)和Func<T,T> 带返回参数的,参数类型是T,返回类型也可以是int,string等..
所以刚才的无参数的例子又可以写成这样:
class Program { static Action print = () => { System.Console.WriteLine("Hello, Delegate!"); }; static void Main(string[] args) { print.Invoke(); } }
再来看看Func<T,TReslut> 第一个T代表参数的类型,第一个TReslut代表返回结果的类型。
如下,参数的类型是int,返回的类型是string.
class Program { static Func<int,string> print = (i) => { return "Hello, Delegate!"+i.ToString(); }; static void Main(string[] args) { System.Console.WriteLine(print.Invoke(0)); } }
输出的结果是:Hello, Delegate!0
再来看看委托的回调函数,如下:
class Program { delegate string callback(string firstName, string lastName); static void Main(string[] argss) { DoCallback("Charlie", "Wang", en_US); DoCallback("Tom", "Chen", ch_ZN); } static void DoCallback(string firstName, string lastName, callback call) { string result=call(firstName, lastName); Console.WriteLine(result); } static string en_US(string firstName, string lastName) { return firstName + " ," + lastName; } static string ch_ZN(string firstName, string lastName) { return lastName+", "+firstName; } }
输出的结果为:
Charlie ,WangChen, Tom
我们还可以将以上代码进一步精简,用Func代替.
class Program { static void Main(string[] argss) { DoCallback("Charlie", "Wang", en_US); DoCallback("Tom", "Chen", ch_ZN); } static void DoCallback(string firstName, string lastName, Func<string,string,string> callback) { string result = callback(firstName, lastName); Console.WriteLine(result); } static string en_US(string firstName, string lastName) { return firstName + " ," + lastName; } static string ch_ZN(string firstName, string lastName) { return lastName+", "+firstName; } }
我们还可以这样写.
class Program { static void Main(string[] argss) { DoCallback("Charlie", "Wang", en_US); DoCallback("Tom", "Chen", ch_ZN); DoCallback("Kevin", "Liu", (lastName, firstName) => { return string.Format("This is {0} {1}", lastName, firstName);}); } static void DoCallback(string firstName, string lastName, Func<string,string,string> callback) { string result = callback(firstName, lastName); Console.WriteLine(result); } static string en_US(string firstName, string lastName) { return firstName + " ," + lastName; } static string ch_ZN(string firstName, string lastName) { return lastName+", "+firstName; } }
输出结果为:
Charlie ,WangChen, TomThis is Kevin Liu
委托在很多时候使用可以精简我们的代码,看起来比较直观,下面是个很经典的案例:
class Program { static void Main(string[] args) { B b = new B(); } } class A { public A() { Print(); } public virtual void Print() { } } class B : A { int x = 1; int y; public B() { y = -1; } public override void Print() { System.Console.WriteLine("x={0},y={1}", x, y); } }
各位读者看看以上代码输出什么?
class Program { static void Main(string[] args) { B b = new B(); b.print(); } } class A { public A() { Print(); } public virtual void Print() { } } class B : A { int x = 1; int y; public Action print = delegate { }; public B() { y = -1; this.print = Print; } public override void Print() { System.Console.WriteLine("x={0},y={1}", x, y); } }
然后再看看以上代码又输出什么?
来自: 昵称10504424 > 《工作》
0条评论
发表
请遵守用户 评论公约
C#中奇妙的操作符重载 - 永不言拜 - 博客园
细心的朋友可能发现,C#虽然可以重载操作符,但和C++比较起来,却有很大的不同。/// 重载运算符true./// <param name="n"></param>public static bool operator true(Namer n)//...
c# 链式编程
Delegate委托之学习心得
Delegate委托之学习心得。Delegate,中文翻译为代理或委托(我更倾向于委托),是一种可以把引用存储为函数的类型,其本质就是函数指针。3) 一个 delegate type 的声明在本质上是创建了一个新的 subtyp...
C# 委托(Delegate) | 菜鸟教程
C# 委托(Delegate) | 菜鸟教程C# 委托(Delegate)delegate int NumberChanger(int n);} static void Main(string[] args) { // 创建委托实例 NumberChanger nc1 = new NumberChanger(AddNum); Numbe...
详解C#委托、时间和Lambda表达式 - 51CTO.COM
这和C的函数指针很像,但是函数指针仅仅包含函数入口地址,而委托是一个类型,它具有比函数指针更强的功能。事实上,方法并不需要和委托声明类型的签名完全一致,.net允许方法的返回值是继承自声明的返...
C#委托四(匿名方法)
/// <summary>/// 声明一个委托,用于实现多播操作/// </summary>/// <param name=”Test”></param>delegate s...
C# 委托?这篇文章让你困惑全摆脱!
// 将输出 string 类型 ''''''''123'''''''' Console.WriteLine(...
c#委托理解简单
static void TransToCN(string str)如图有父窗体和子窗体两个窗体,现在我想实现当点击父窗体中按钮时弹出子窗体(当然这个超级简单),在弹出子窗体后,在子窗体的文本框中输入内容,点击关闭按钮后子...
C#委托,事件
// 将事件处理程序添加到事件的调用列表中(即事件布线) myText.Changed += new MyText.ChangedEventHandler(myText_Changed); string str = "";...
微信扫码,在手机上查看选中内容