知识在于积累。

前言

好久没写博客了,因为在看《CLR via C#》的时候,竟然卡在了分部方法这一小节几天没下去。今天重新认真阅读,有些感悟,所以在此记录。

然后。

每天早晨第一句,《CLR via C#》真有意思。

分部类

我们用 partial 关键字告诉C#编译器:类、结构或接口的定义源代码可能要分散到一个或多个源代码文件中。

将类型源代码分散到多个文件的原因有三个:

  • 源代码控制

  假定类型定义包含大量的源代码,一个程序员把它从源代码控制系统中签出(check out)以进行修改。没有其他程序员能同事修改这个类型,除非之后执行合并。

  使用 partial 关键字可将类型的代码分散到多个源代码文件中,每个文件都可以单独签出,多个程序员能同时编辑类型。

  • 在同一个文件中将类或结构分解成不同的逻辑单元

  可以创建一个类型来提供多个功能,让类型能提供完整的解决方案。为了简化实现,有时会在一个源代码文件中重复声明同一个分部类型。然后分部类型的每个部分都实现一个功能,并配以它的全部字段、属性、方法、事件等。这样就可方便的看到组合以提供一个功能完整的全体成员,从而简化代码。

  与此同时,可以方便的将分部类型的一部分注释掉,以便从类中删除一个完整的功能,代之以另一个实现(通过分部类型的一个新的部分)。

  • 代码拆分

  在 Microsoft Visual Studio 中创建新项目时,一些源代码文件会作为项目一部分自动创建。这些源代码包含模板,能为项目开个好头。使用 Visual Studio 在设计图面上拖放控件时,Visual Studio 自动生成源代码,并将代码拆分到不同的源文件中。

  这就提高的开发效率。

要将 paritial 关键字应用于所有文件中的类型。

这些文件编译到一起时,编译器会合并代码,在最后 .exe 或 .dll 程序集文件(或 .netmodule 模块文件)中生成单个类型。

“分类类型”功能完全由C#编译器实现,CLR对此一无所知,这解释了一个类型的所有源代码文件为什么必须使用相同的编程语言,而且必须作为一个编译单元编译到一起。

分部方法

假如我们现在在写一个工具,里面包含着C#源代码文件。我们写的这个工具有个功能是,需要在代码的某些位置定制类型的行为。

一般我们这么做,调用虚方法来进行定制。那么这个工具生成的代码必须包含虚方法的定义。另外这些方法的实现是什么事情都不做,直接返回了事。

现在如果想定制类的行为,就必须从基类派生并定义自己的类,重写虚方法来实现自己想要的行为。

看下面代码:

好。刚刚我们说的这个方法有两个问题。

  • 类型必须是非密封的。不能用于值类型(值类型隐式密封)、不能用于静态方法(静态方法不能重写)。
  • 效率问题。定义一个类型只是为了重写一个方法,这会浪费少量系统资源。另外,即使不想重写某个虚方法的行为,基类代码仍然需要调用一个什么都不做、直接就返回的虚方法。

我们现在利用分部方法就可以解决上面的问题。

修改一下刚刚的代码:

现在我们这个代码:

  • 类型可以密封,也可以是静态类、值类型。
  • 工具和开发者所生成的代码真的是一个类型定义的两个部分。
  • 工具生成的代码包含分部方法的声明,要用 partial 关键字标记,没有主体。
  • 开发者生成的代码实现这个声明,该方法也需要用 partial 关键字标记,有主体。

编译完成之后与虚方法实现的代码效果相同。

分部方法还有一个巨大的提升就是,不会生成多余的IL指令,使运行效率提升。

如果不想修改工具生成的类型的行为,那么根本不需要提供自己的源代码文件,如果没有实现分部方法,编译器就不会生成任何代表分部方法的元数据,也就是说编译器不会生成任何调用分部方法的IL指令。

更少的元数据和更少的IL指令,运行时的性能就能得到提升。

另外一些规则和原则

  • 分部方法只能在分部类或结构中声明。
  • 分部方法的返回类型始终是 void,任何参数都不能用 out 符号标记。
  • 分部方法的声明和实现必须具有完全一致的签名。
  • 如果没有对应的实现部分,便不能再代码中创建一个委托来引用这个分部方法。
  • 分部方法总是被视为 private 方法,但是C#编译器禁止在分部方法声明之前添加 private 关键字。

[C#学习笔记]分部类和分部方法的更多相关文章

  1. C#综合揭秘——分部类和分部方法

    在面向对象的“封装闭合性”开发原则中,一向提倡的是把独立的功能封装在一个类里面的!但从Visual Studio 2005开发,系统提供了一个分部类的开发方式一直受到争议,很多人认为把同一类的功能分布 ...

  2. C#中的分部类和分部方法:partial

    这篇文章主要介绍了C#中的分部类和分部方法,讲解了类的拆分和方法的定义的拆分,需要的朋友可以参考下可以将类或结构.接口或方法的定义拆分到两个或多个源文件中.每个源文件包含类型或方法定义的一部分,编译应 ...

  3. C#中分部类和分部方法的应用

    本篇文章介绍了,C#中分部类和分部方法的应用.需要的朋友参考下     分部类(Partial Class)在C#2.0引入,分部方法(Partial Method)在C#3.0引入,这两个语法特性都 ...

  4. C# partial修饰符_分部类_分部方法

    今天翻了翻书,发现自己还是遗留下不少基础性的东西,老实说,不管一些基础的东西用到不用到都很应该了解,因为基础毕竟学习量不是很大. 一.分部类 什么是部分类呢?简单来说就是将一个类型或方法拆分到两个或多 ...

  5. 分部类,分部方法 - 修饰符partial

    一.分部类 什么是部分类呢?简单来说就是将一个类型或方法拆分到两个或多个源文件中,每个源文件只包含类型定义的一部分. 当使用自动生成的源时,无须重新创建源文件便可将代码添加到类中.Visual Stu ...

  6. C# 分部类与分部方法

    一.定义 分部方法是指能够使编码人员跨多个代码文件实现类型的语法.简而言之.它可以让我们在一个文件中构建方法原型,而在另一个文件中实现 使用分部方法和分部类需要使用关键词partial,且紧靠在cla ...

  7. c# partial 分部类和分部方法

    一.partial 它是一个关键字修饰符.可以将类或结构.接口或方法的定义拆分到两个或更多个源文件中. 每个源文件包含类型或方法定义的一部分,编译应用程序时将把所有部分组合起来.修饰符不可用于委托或枚 ...

  8. 利用partial关键字声明分部类和分部方法

    一.分部类 1.分部类的定义:简单的说,分部类就是把一个类拆分成多个类,每个类文件只包含其中的一部分,类.结构.接口.方法都可以拆分,在定义的时候加上partial修饰符. 注意:分部类必须属于同一命 ...

  9. C# partial分部类和分部方法

    1.https://www.cnblogs.com/xcsn/p/7533238.html 它是一个关键字修饰符.可以将类或结构.接口或方法的定义拆分到两个或更多个源文件中. 每个源文件包含类型或方法 ...

随机推荐

  1. Eutils用法总结

    好久没更新了,这里都长草了... 总结下Eutils的用法,参考<E-utilities Quick Start>,没时间看英文的可以参考下. 简介 Eutils全称是The Entrez ...

  2. 深入浅出 Java Concurrency (6): 锁机制 part 1 Lock与ReentrantLock

      前面的章节主要谈谈原子操作,至于与原子操作一些相关的问题或者说陷阱就放到最后的总结篇来整体说明.从这一章开始花少量的篇幅谈谈锁机制. 上一个章节中谈到了锁机制,并且针对于原子操作谈了一些相关的概念 ...

  3. urllib2异常处理(七)

    urllib2 的异常错误处理 在我们用urlopen或opener.open方法发出一个请求时,如果urlopen或opener.open不能处理这个response,就产生错误. 这里主要说的是U ...

  4. python操作excel表格文件--使用xlrd模块

    原文: http://www.cnblogs.com/lhj588/archive/2012/01/06/2314181.html 引言: 实际工作中,可能很多情况下都会用到excel表格,像如果不需 ...

  5. 39. Combination Sum + 40. Combination Sum II + 216. Combination Sum III + 377. Combination Sum IV

    ▶ 给定一个数组 和一个目标值.从该数组中选出若干项(项数不定),使他们的和等于目标值. ▶ 36. 数组元素无重复 ● 代码,初版,19 ms .从底向上的动态规划,但是转移方程比较智障(将待求数分 ...

  6. my sql存储过程 基本使用

    --------------创建不带参数的存储过程----------------- DELIMITER;; drop PROCEDURE if EXISTS selectStudent; creat ...

  7. java CPU 100% 排查

    一个应用占用CPU很高,除了确实是计算密集型应用之外,通常原因都是出现了死循环. (友情提示:本博文章欢迎转载,但请注明出处:hankchen,http://www.blogjava.net/hank ...

  8. Python time、datetime

    简介: 记录一下 Python 如何获取昨天.今天.明天时间及格式化. 1.今天 In [1]: import time In [2]: print time.strftime('%Y.%m.%d', ...

  9. spring boot 2

    服务端验证: // 1.修改实体 @Min(value = 18,message = "必须大于18岁") private int age; // 2.修改add方法 @PostM ...

  10. vnc安装

    安装命令:yum install tigervnc-server 一.启动VNC服务 输入命令 vncserver ps -ef|grep Xvnc vncserver -geometry 800x6 ...