知识大全 C# 3.0中的分部方法

Posted

篇首语:奋斗者在汗水汇集的江河里,将事业之舟驶到了理想的彼岸。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 C# 3.0中的分部方法相关的知识,希望对你有一定的参考价值。

C# 3.0中的分部方法  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!

  分部方法的语法

  在看C#语言的What s New时 突然发现新特性列表的最后 多出了一个 Partial Method Definitions 但并不像其他新特性一样有超链接链接到其说明 上网搜索了一下 关于分部类型的信息非常少 尤其是中文信息 只有CSDN的 周融 在其《C# 语言在 Visual Studio Orcas Beta 上的新增功能(二) 》一文的最后提到了这个分部方法 但没有进一步说明 英文技术文章中 倒是有两篇不错的 heard aspx 和 partial methods what why and how aspx

  又仔细看了一下MSDN Library for Visual Studio Beta 终于对这个语言特性有所了解 在这里介绍一下 希望对大家有所帮助

  分部方法的定义和分部类型类似 只需在方法定义前添加partial关键字 但分部方法只能拆分成两个部分——一部分是定义声明(Definition Declaration) 另一部分是实现声明(Implement Declaration) 其中定义声明看上去和抽象方法类似

  partial class CA

  

  // ……

  private void partial M() // 定义声明|

  而实现声明看上去和普通方法类似

  private void partial M() // 实现声明

  

  // 方法体

  

  在调用分部方法时 和调用其他方法一样

  CA a = new CA()

  a M()

  只是 如果只有定义声明而没有编写实现声明 则编译器不会发射(Emit)该方法和调用该方法的语句的元数据与IL代码 换言之 如果没有编写实现声明 则编译得到的程序集中 CA类型里并没有M这个方法

  使用分部方法的注意事项

  分部方法的语法非常简单 但有一些事项要注意

  如果没有写实现声明 则不会发射方法调用代码 也不会对参数进行求值 因此 对于下面的例子

  

  class CA partial void M(int i); static void Main() CA a = new CA(); int i = ; a M(i++);

  分部方法M只有定义声明 没有实现声明 因此也不会发射调用该方法的代码 a M(i++) 因此也不会对i++进行求值 所以最终i的值依然是 但如果为M编写了实现声明 则a M(i++)的代码会被编译到最终的程序集中 同时参数也被求值 i的值将被变为

  分部方法只能出现在分部类中

  分部方法必须是私有(private)的 并且返回值类型必须是void

  分部方法可以带有参数 并且其参数可以带有this params和ref修饰符 但不能带有out修饰符

  分部方法不可以是虚拟(virtual)的

  分部方法不可以是外部(extern)的

  分部方法可以是静态(static)的 也可以是不安全(unsafe)的

  分部方法可以是泛型方法 泛型约束必须放置在定义声明中 但也可以在事先声明中重复说明 在定义声明和实现声明中 类型参数和类型参数的名字不一定必须一致

  不能将分部方法封装到一个委托中

  分部方法的应用场景

  分部方法和分部类型的初衷是类似的 一方面可以使得不同的开发者能够同时编写一个类型的不同部分 另一方面可以分离自动生成的代码和用户手写的代码 和分部类型一样 分部方法也会在编译初期被合并成一个方法定义 猜测 从微软的角度来看 第二个 初衷 可能才是真正的初衷

  由此 分部方法有如下几个应用场景 (场景 出自In Case You Haven t Heard这篇文章「 case you haven t heard aspx」) 场景 出自Visual Studio 的Linq to SQL技术 而场景 则是Anders Liu自已臆想出来的

  场景 轻量级事件处理

  有的时候 自动生成的代码需要事件这类语言构造来通知用户对某些操作进行处理 但实际上用于编写的代码就位于自动生成的类型之中 此时 或者需要触发一个事件 或者就需要生成一个virtual方法来让用户继承 但无论是事件还是继承 开销都是比较大的 所以可以通过分部方法来实现轻量级的处理方式 如下面的类 (本例子引用自前述的In Case You Haven t Heard一文)

  

  partial class Customer string name; public string Name get return name; set OnBeforeUpdateName(); OnUpdateName(); name = value; OnAfterUpdateName(); partial void OnBeforeUpdateName(); partial void OnAfterUpdateName(); partial void OnUpdateName();

  这里定义了三个分部方法 其意义不言而喻 假设这是系统自动生成的代码 则我们只需在另外一个源代码文件中的partial class Customer中实现这几个分部方法即可

  场景 自定义DataContext中的Insert Update Delete方法

  当使用Linq to SQL向项目中加入了实体类之后 还会创建一个XxxDataContext类 这个类继承自DataContext类 并且是partial的 这个类封装了具体的数据库操作功能(实体类仅封装数据库中的数据) 如对象的插入 更新和删除等

  下面我们来看一下这个自动生成的类定义

  

  [System Data Linq Mapping DatabaseAttribute(Name= AdventureWorks )] public partial class AdventureWorksDataContext : System Data Linq DataContext private static System Data Linq Mapping MappingSource mappingSource   = new AttributeMappingSource(); #region Extensibility Method Definitions partial void OnCreated(); partial void InsertAWBuildVersion(AWBuildVersion instance); partial void UpdateAWBuildVersion(AWBuildVersion instance); partial void DeleteAWBuildVersion(AWBuildVersion instance);

  这里我们可以看到一系列的partial方法 其中第一个OnCreated实际上属于场景 中描述的情况 是一个轻量级的事件 表示 DataContext环境对象创建完毕 而其他partial方法则用于自定义DataContext的IUD操作 对于每一个表(实体类) 这里都会出现一组InsertXxx UpdateXxx和DeleteXxx方法 如果我们希望自定义删除行为(如希望将一个IsDelete字段设置为 true来表示已删除) 则可以在另一个文件中扩展这个partial类 并为对应的Delete方法提供实现声明

  场景 新的调试信息输出方法

  这是Anders Liu臆想的场景 在分部方法的协助下 我们可以写出这样的代码

  

  partial class CA partial void DebugPrint(string msg); void F() DebugPrint( aaa ); partial class CA #if DEBUG partial void DebugPrint(string msg); Debug WriteLine(msg); #endif

  这样做的好处在于 我们还是反过来说罢 如果不这样做 必须在每次调用调试代码时都加入#if判断 而这样可以将调试代码都写成方法 在一处用#if进行判断

  缺点在于 由于分部方法必须是私有的 所以必须针对每个类写一套调试代码

  小结

cha138/Article/program/net/201311/13680

相关参考

知识大全 C#分部方法(Partial Method)讨论

C#分部方法(PartialMethod)讨论  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  C

知识大全 深入理解C# 3.0的五项主要改进

深入理解C#3.0的五项主要改进  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!隐型局部变量  C#

知识大全 Visual C# 3.0 新特性概览

VisualC#3.0新特性概览  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!在发布VisualS

知识大全 C#3.0之对象与集合初始化

C#3.0之对象与集合初始化  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  我们知道在C#中要初

知识大全 关于C#3.0 新特性之对象构造者

关于C#3.0新特性之对象构造者  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  C#中加入的对象

知识大全 C#3.0之自动属性和对象初始化器

C#3.0之自动属性和对象初始化器  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!C#中定义属性更加

知识大全 C#中的基元类型

C#中的基元类型  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  这篇文章我想复习下C#中的基元类

知识大全 C#枚举中的位运算

C#枚举中的位运算  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  本文介绍C#位运算的处理方法第

知识大全 C#中的“Squiggles”特性

C#中的“Squiggles”特性  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  从VBNET开

知识大全 C#中的eval()函数

C#中的eval()函数  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  可以这样说绝大多数的大型