C# 1.1里,声明和使用委托要求你有委托和一个在委托被触发时具有匹配签名的能够执行的方法,以及一个将命名方法与委托关联的分配语句。作为C# 2.0的新特性,匿名方法基本上能够提供与先前命名方法相同的功能,但是它已经不再需要一个在关联到委托之前就明确创建的方法了。
你可以把匿名方法想象为一个实现与委托进行关联这项功能的便捷途径。如果同时看一下匿名方法实现和命名方法实现所取得IL结果,你会发现这两者之间的差别非常小。当编译器碰到匿名方法的时候,它会在类里面创建一个命名方法,并将它与委托进行关联。所以匿名方法在运行期间与命名方法的性能非常类似——性能的增加体现在开发人员的生产效率上,而不是运行期间的执行上。
如何使用匿名方法
多用代码少用说教来解释和理解匿名方法会容易一些。下面的例子应该能够说明你自己可以如何利用匿名方法的优势:
例1——基础知识
使用匿名方法很简单。你只需要把匿名方法放在你通常放命名方法的关联语句里。在下面这个例子里,我把匿名方法和示例1的委托关联在一起:
示例列表1
#region Simple example - Example1
privatedelegatevoidExample1();
privatevoid btnExample1_Click(object sender, EventArgs e)
{
//Declare an instance of the Example1 delegate.
// You can see where I'm using the anonymous
// method in place of a named method - it follows
// the delegate() keyword.
Example1 example =
newExample1(
delegate()
{
MessageBox.Show("Example1");
});
example();
}
#endregion
例2——变量范围
任何在匿名方法里声明的变量的范围都不会超出匿名方法的代码块。但是,匿名方法确实具有访问它们代码块之外的变量的能力,只要这些变量在匿名方法所使用的范围里。这些变量被微软称为外部变量。下面示例2显示了匿名方法如何引用外部变量:
示例列表2
#region Variable scope example - Example2
privatedelegatevoidExample2();
privatevoid btnExample2_Click(object sender, EventArgs e)
{
//Setup our parameters.
string firstName = "Zach";
string lastName = "Smith";
//Create an instance of the Example2 delegate with an
// anonymous method.
Example2 example =
newExample2(
delegate() {
MessageBox.Show(firstName + " " + lastName);
});
//Execute the delegate.
example();
}
#endregion
要注意的是,根据MSDN的文档,匿名方法里的ref和out参数无法被访问到。
例3——参数的传递
你可以将参数传递给匿名方法,方式就和你处理引用命名方法参数的委托一样。下面的示例3说明这种类型的功能:
示例列表3
#region Parameter example - Example3
privatedelegatevoidExample3(string firstName, string lastName);
privatevoid btnExample3_Click(object sender, EventArgs e)
{
//Setup our parameters.
string parameter1 = "Zach";
string parameter2 = "Smith";
//Create an instance of the Example3 delegate with an
// anonymous method.
Example3 example =
newExample3(
delegate(string firstName, string lastName)
{
MessageBox.Show("Example3: " + firstName + " " + lastName);
});
//Execute the delegate.
example(parameter1, parameter2);
}
#endregion
例4——多个方法的关联
就和命名方法一样,将多个匿名方法与同一个委托进行关联是可能的。这在很多情况下会非常有用——首先想到的是把一个简单的处理程序添加给按钮的点击事件。下面的代码(示例4)显示了一个委托,它同时带有与之相关联一个匿名方法和一个命名方法:
示例列表4
#region Multiple method association (stacking) - Example4
privatedelegatevoidExample4(string firstName, string lastName);
privatevoid btnExample4_Click(object sender, EventArgs e)
{
//Setup our parameters.
string parameter1 = "Zach";
string parameter2 = "Smith";
//Create an instance of the Example4 delegate with an
// anonymous method.
Example4 example =
newExample4(
delegate(string firstName, string lastName)
{
MessageBox.Show("Example4: " + firstName + " " + lastName);
});
//Add another method to the delegate - this time
// a named method.
example += newExample4(Example4NamedMethod);
//Execute the delegate.
example(parameter1, parameter2);
}
privatevoid Example4NamedMethod(string firstName, string lastName)
{
MessageBox.Show("Example4Method: " + firstName + " " + lastName);
}
#endregion
例5——将匿名方法作为参数传递
就和命名方法一样,将匿名方法作为参数传递给函数是可能的。这并不是一个我认为会通常使用的特性,但是我敢肯定未来会有这种需要。下面的代码(例5)说明了这种类型的功能,它将一个命名方法作为参数传递给了函数:
示例列表5
#region Passing anonymous methods - Example5
privatedelegatevoidExample5(string firstName, string lastName);
privatevoid btnExample5_Click(object sender, EventArgs e)
{
//Execute Passit and pass the anonymous method.
Passit((Example5)delegate(string firstName, string lastName)
{
MessageBox.Show("Example5: " + firstName + " " + lastName);
});
//Execute Passit with the named method.
Passit(Example5NamedMethod);
}
privatevoid Example5NamedMethod(string firstName, string lastName)
{
MessageBox.Show("Example5Method: " + firstName + " " + lastName);
}
privatevoid Passit(Example5 example)
{
example("Zach", "Smith");
}
#endregion
例6—-访问类成员
这是对上面例2的变量范围的扩展。但是,这个例子(例6)说明了匿名参数还能够在它们的代码块之外执行命名方法:
示例列表6
#region Accessing class members - Example6
privatedelegatevoidExample6();
privateint _customerId;
privatestring _customerCode;
publicint CustomerID
{
get { return _customerId; }
set { _customerId = value; }
}
publicstring CustomerCode
{
get { return _customerCode; }
set { _customerCode = value; }
}
privatevoid btnExample6_Click(object sender, EventArgs e)
{
//Populate out properties.
this.CustomerID = 90;
this.CustomerCode = "1337HK";
//Setup the delegate/anonymous method.
Example6 example =
newExample6(
delegate
{
this.ShowCustomer(this.CustomerID, this.CustomerCode);
});
//Execute the delegate.
example();
//Change the properties.
this.CustomerID = 54;
this.CustomerCode = "L4M3";
//Execute the delegate again.
// Notice that the new values are reflected.
example();
}
privatevoid ShowCustomer(int customerId, string customerCode)
{
MessageBox.Show(
String.Format("CustomerID: {0}nCustomer Code: {1}",
customerId, customerCode));
}
#endregion
要注意的是,我两次调用了与匿名方法相关联的委托。你可能会发现一个很有趣的事情:在这些调用中,方法会输出两组不同的值。这是因为用在匿名方法里的外部变量在创建匿名方法的时候被引用。这意味着对这些变量的任何更改都会在匿名函数访问变量的时候被反映出来。
你可能还注意到在这个实例里委托关键字后面没有括号。当匿名方法不需要带参数的时候,后面的括号是可选的。
评论
我希望本文已经说明如何使用匿名方法。虽然它们还不是革命性的,但是它们是C#演化成为一门程序员友好的语言过程中的一个重要步骤。
分享到:
相关推荐
在C#编程环境下开发MES车间信息控制系统,可以充分利用.NET框架的优势,实现高效、稳定且易维护的系统。 C#是一种面向对象的编程语言,由微软公司开发,广泛应用于Windows平台的应用程序开发。其语法简洁明了,支持...
C#2.0是Microsoft .NET框架的一部分,它在原有的C#版本基础上进行了显著的增强,引入了一系列重要...这种设计哲学确保了C#2.0的更新既强大又平滑,使得开发者能够在不破坏现有代码的基础上,充分利用新功能带来的便利。
通过这些工具,开发者可以轻松实现任务并行化,提高程序的执行效率,充分利用现代硬件的多核优势。 PLINQ(Parallel LINQ)是另一个重要的新特性,它是LINQ(Language Integrated Query)在并行处理领域的扩展。...
C#2005是该语言的一个早期版本,它引入了泛型、匿名方法、迭代器等新特性,提高了代码的可重用性和执行效率,为CRM系统的开发提供了坚实的语法基础。 2. .NET框架:CRM系统基于.NET Framework运行,这是一个由微软...
无论是初学者还是经验丰富的程序员,都应该定期查阅并理解最新的C#语言规范,以便在实际开发中能够充分利用其特性和优势。通过深入学习这三个不同版本的规范,可以见证C#语言从早期版本到现代版本的演进历程,更好地...
《C# 3.0 文档精华》 C# 3.0 是.NET Framework的重要版本,引入了...通过学习和实践这些知识点,你可以充分利用C# 3.0的优势,编写出更高效、更易于维护的软件。在你的编程旅程中,这份文档将是不可或缺的参考资料。
这些特性使得开发者可以充分利用多核处理器的优势,同时保持代码的清晰性和可读性。 C#还引入了动态类型和匿名函数,动态类型允许在运行时确定变量的类型,而匿名函数(如lambda表达式)则为事件处理和 LINQ 查询...
在.NET框架下,C#能够充分利用CLR(Common Language Runtime)的优势,提供跨平台开发的可能性。 二、.NET框架结构与原理 .NET框架是微软开发的应用程序运行环境,包括类库、CLR和开发工具。类库提供了大量的预定义...
9. **多线程与并发**:了解如何在C#中实现并行和并发编程,以充分利用多核处理器的优势。 10. **文件和I/O操作**:学习读写文件,处理流,以及如何进行网络通信。 11. **设计模式**:引入常见的设计模式,如工厂...
5. **并行 LINQ (PLINQ)**:是LINQ的一个扩展,允许开发者编写并行查询,充分利用多核处理器的优势提高程序执行效率。 6. **Task类**:作为异步编程的核心,Task类为编写异步代码提供了新的模型,使得异步操作更...
总的来说,C#与VB.NET代码互转工具是.NET开发者的一个实用辅助工具,能够帮助他们充分利用两种语言的优势,提高开发效率,尤其是在团队成员使用不同编程语言的项目中。不过,理解和掌握两种语言的基本语法和特性仍然...
C# 3.0是微软.NET Framework 3.5的一部分,是C#语言的一个重要升级,引入了许多新的特性和改进,极大地提升了开发人员的...通过深入学习和理解这些内容,开发者能够充分利用C# 3.0的优势,编写出更高效、更简洁的代码。
本系统采用C#作为主要开发语言,充分利用了.NET框架的强大功能,结合数据库技术,为用户提供了一整套完整的项目管理解决方案。 C#是一种面向对象的编程语言,由微软公司推出,旨在提高开发者的生产力,同时支持Web...
8. **多线程与并发编程**:C#提供了一系列工具和类库(如Task、ThreadPool等)来处理多线程和并发问题,以充分利用多核处理器的优势。 9. **设计模式**:学习并应用常见的设计模式(如工厂模式、单例模式、装饰器...
《深入.NET平台和C#编程(.NET OOP)DLC3指导3》是针对.NET框架和C#编程语言深入学习的教程,旨在帮助开发者更好地理解和掌握.NET开发技术。本资源可能包含一系列章节、实例代码、练习题等,以加深对.NET对象导向编程...
10. **多线程与并发**:C#提供了多种并发模型,如线程池、异步操作和`Task`,理解和熟练使用这些工具能帮助开发者编写出并行和并发友好的代码,充分利用多核处理器的优势。 以上内容只是C#程序开发技巧大全第7章...
C# 3.0是.NET Framework 3.5的一部分,引入了许多重要的新特性和改进,极大地扩展了C#编程语言的能力。...通过学习和熟练掌握这些知识点,开发者能够充分利用C# 3.0的优势,构建高效、简洁的.NET应用程序。
这个“C#2.0锐利体验ppt”很可能是针对C# 2.0新特性和增强功能的一个演示文稿,旨在帮助开发者深入理解和充分利用这一版本的语言特性。 在C# 2.0中,引入了许多关键的改进和新功能,其中包括: 1. 泛型:泛型是C# ...
C#是一种现代化、类型安全的面向对象编程语言,由微软公司开发,主要用于构建Windows应用程序、Web应用程序以及移动应用。...通过学习C#,你将能够开发出高效、可靠的软件解决方案,充分利用.NET生态系统的优势。