查看: 701|回复: 0
打印 上一主题 下一主题

[其他] 委托 匿名 Lambda的区分

[复制链接]
may    

8830

主题

81

听众

7万

积分

首席设计师

Rank: 8Rank: 8

纳金币
52336
精华
343

最佳新人 热心会员 灌水之王 活跃会员 突出贡献 荣誉管理 论坛元老

跳转到指定楼层
楼主
发表于 2015-10-18 00:07:58 |只看该作者 |倒序浏览

1 委托是安全封装方法的类型,类似于 C 和 C++ 中的函数指针。 与 C 函数指针不同的是,委托是面向对象的、类型安全的和可靠的。 委托的类型由委托的
名称确定。Delegate 类,委托是一种数据结构,它引用静态方法或引用类实例及该类的实例方法,有属性和方法。
分为带有命名方法的委托与带有匿名方法的委托(C# 编程指南)
// 可以放在任何一个空文件中作全局MessengerCallback类型
public delegate void MessengerCallback();
public delegate void MessengerCallback<T>(T arg1);
public delegate void MessengerCallback<T,U>(T arg1, U arg2);
public delegate void MessengerCallback<T,U,V>(T arg1, U arg2, V arg3);

2 匿名函数是一个“内联”语句或表达式,可在需要委托类型的任何地方使用。 可以使用匿名函数来初始化命名委托,或传递命名委托(而不是命名委托类型
)作为方法参数。
eg: button1.Click += delegate(System.Object o, System.EventArgs e) { System.Windows.Forms.MessageBox.Show("Click!"); };

3 “Lambda 表达式”(lambda expression,)是一个c,Lambda表达式基于数学中的λ演算得名,直接对应于其中的lambda抽象(lambda abstraction),是一个
匿名函数,即没有函数名的函数。
形参列表=>函数体 (input parameters) => expression
仅当 lambda 只有一个输入参数时,括号才是可选的;否则括号是必需的。 括号内的两个或更多输入参数使用逗号加以分隔:
() => SomeMethod() --无参
del myDelegate = x => x * x 等价于 del myDelegate = (x) => x * x; ---1参
(x, y) => x == y 有时,编译器难以或无法推断输入类型。 如果出现这种情况,你可以按以下示例中所示方式显式指定类型:
(int x, string s) => s.Length > x

Lambda表达式的本质是“匿名方法”,即当编译我们的程序代码时,“编译器”会自动将“Lambda表达式”转换为“匿名方法”,如下例:
string[] names={"agen","balen","coure","apple"};
string[] findNameA=Array.FindAll<string>(names,delegate(string v){return v.StartsWith("a");});
string[] findNameB=Array.FindAll<string>(names,v=>v.StartsWith("a"));
上面中两个FindAll方法的反编译代码如下:
string[]findNameA=Array.FindAll<string>(names,delegate(stringv){returnv.StartsWith("a");});
string[]findNameB=Array.FindAll<string>(names,delegate(stringv){returnv.StartsWith("a");});
从而可以知道“Lambda表达式”与“匿名方法”是可以划上等号的,只不过使用“Lambda表达式”输写代码看上去更直观漂亮,不是吗?

///////////////////////////////
ps:匿名方法是C#2.0引入的一个新特性,它允许开发者内联(inline)声明自己的函数代码而无须使用委托函数(delegate function。
匿名方法通常在:
1. 需要一个临时方法,该方法使用次数极少;
2. 这个方法的代码很短,甚至可能比方法声明都短的情况下使用。
利用delegate关键字创建匿名方法,如下:
button1.Click += delegate(System.Object o, System.EventArgs e)
{
System.Windows.Forms.MessageBox.Show("Click!");
};
/////////////////////////////
----发展史:
1. 在C# 1.1里,声明和使用委托要求你有委托和一个在委托被触发时具有匹配签名的能够执行的方法,以及一个将命名方法与委托关联的分配语句。
2. 作为C# 2.0的新特性,匿名方法基本上能够提供与先前命名方法相同的功能,但是它已经不再需要一个在关联到委托之前就明确创建的方法了。
3. C#3.0中提供了一个新特性--Lambda表达式,它提供了完成相同目标的更加简洁的格式。
class Test
{
    delegate void TestDelegate(string s);
    static void M(string s)
    {
        Console.WriteLine(s);
    }

    static void Main(string[] args)
    {
        // Original delegate syntax required
        // initialization with a named method.
        TestDelegate testDelA = new TestDelegate(M);

        // C# 2.0: A delegate can be initialized with
        // inline code, called an "anonymous method." This
        // method takes a string as an input parameter.
        TestDelegate testDelB = delegate(string s) { Console.WriteLine(s); };

        // C# 3.0. A delegate can be initialized with
        // a lambda expression. The lambda also takes a string
        // as an input parameter (x). The type of x is inferred by the compiler.
        TestDelegate testDelC = (x) => { Console.WriteLine(x); };

        // Invoke the delegates.
        testDelA("Hello. My name is M and I write lines.");
        testDelB("That's nothing. I'm anonymous and ");
        testDelC("I'm a famous author.");

        // Keep console window open in debug mode.
        Console.WriteLine("Press any key to exit.");
        Console.ReadKey();
    }
}

///////////////////////////////////////
共有两种匿名函数,以下主题中分别讨论了这些函数:
1. Lambda 表达式
2.匿名方法
有一种情况下,匿名方法提供了 Lambda 表达式中所没有的功能。 您可使用匿名方法来忽略参数列表。 这意味着匿名方法可转换为具有各种签名的委托。 这

对于 Lambda 表达式来说是不可能的.
通过使用匿名方法,由于您不必创建单独的方法,因此减少了实例化委托所需的编码系统开销。
分享到: QQ好友和群QQ好友和群 腾讯微博腾讯微博 腾讯朋友腾讯朋友 微信微信
转播转播0 分享淘帖0 收藏收藏0 支持支持0 反对反对0
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

手机版|纳金网 ( 闽ICP备2021016425号-2/3

GMT+8, 2024-12-1 08:49 , Processed in 0.183217 second(s), 29 queries .

Powered by Discuz!-创意设计 X2.5

© 2008-2019 Narkii Inc.

回顶部