[C#学习笔记]分部类和分部方法
知识在于积累。
前言
好久没写博客了,因为在看《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#学习笔记]分部类和分部方法的更多相关文章
- C#综合揭秘——分部类和分部方法
在面向对象的“封装闭合性”开发原则中,一向提倡的是把独立的功能封装在一个类里面的!但从Visual Studio 2005开发,系统提供了一个分部类的开发方式一直受到争议,很多人认为把同一类的功能分布 ...
- C#中的分部类和分部方法:partial
这篇文章主要介绍了C#中的分部类和分部方法,讲解了类的拆分和方法的定义的拆分,需要的朋友可以参考下可以将类或结构.接口或方法的定义拆分到两个或多个源文件中.每个源文件包含类型或方法定义的一部分,编译应 ...
- C#中分部类和分部方法的应用
本篇文章介绍了,C#中分部类和分部方法的应用.需要的朋友参考下 分部类(Partial Class)在C#2.0引入,分部方法(Partial Method)在C#3.0引入,这两个语法特性都 ...
- C# partial修饰符_分部类_分部方法
今天翻了翻书,发现自己还是遗留下不少基础性的东西,老实说,不管一些基础的东西用到不用到都很应该了解,因为基础毕竟学习量不是很大. 一.分部类 什么是部分类呢?简单来说就是将一个类型或方法拆分到两个或多 ...
- 分部类,分部方法 - 修饰符partial
一.分部类 什么是部分类呢?简单来说就是将一个类型或方法拆分到两个或多个源文件中,每个源文件只包含类型定义的一部分. 当使用自动生成的源时,无须重新创建源文件便可将代码添加到类中.Visual Stu ...
- C# 分部类与分部方法
一.定义 分部方法是指能够使编码人员跨多个代码文件实现类型的语法.简而言之.它可以让我们在一个文件中构建方法原型,而在另一个文件中实现 使用分部方法和分部类需要使用关键词partial,且紧靠在cla ...
- c# partial 分部类和分部方法
一.partial 它是一个关键字修饰符.可以将类或结构.接口或方法的定义拆分到两个或更多个源文件中. 每个源文件包含类型或方法定义的一部分,编译应用程序时将把所有部分组合起来.修饰符不可用于委托或枚 ...
- 利用partial关键字声明分部类和分部方法
一.分部类 1.分部类的定义:简单的说,分部类就是把一个类拆分成多个类,每个类文件只包含其中的一部分,类.结构.接口.方法都可以拆分,在定义的时候加上partial修饰符. 注意:分部类必须属于同一命 ...
- C# partial分部类和分部方法
1.https://www.cnblogs.com/xcsn/p/7533238.html 它是一个关键字修饰符.可以将类或结构.接口或方法的定义拆分到两个或更多个源文件中. 每个源文件包含类型或方法 ...
随机推荐
- Linux 性能分析的前 60 秒
编译自:http://techblog.netflix.com/2015/11/linux-performance-analysis-in-60s.html作者: Brendan Gregg转载自:h ...
- leetcode205
public class Solution { public bool IsIsomorphic(string s, string t) { if (s.Length != t.Length) { r ...
- maven常用命令集合
作者:ydlmlh 原文:http://ydlmlh.iteye.com/blog/2158973 抽了点时间,整理了一些maven常用命令参数,以便参考:参考了maven官网和网上其他一些maven ...
- ubuntu上安装 MySQL 启动/停止 连接MySQL
1.Ubuntu上安装MySQL服务 1.安装服务端 sudo apt-get install mysql-server 2.安装客户端 sudo apt-get install m ...
- Redis 哨兵模式 带密码单机
语法 https://segmentfault.com/a/1190000002680804 启动3台redis 6379,6380,6381 cp 多个redis.conf文件 开启daemoniz ...
- C语言实现 读取写入ini文件实现(转)
#include <stdio.h> #include <string.h> /* * 函数名: GetIniKeyString * 入口参数: title * 配置文件中一组 ...
- 新手C#面向对象的学习2018.08.06
class Person//声明一个Person类 { //类中的声明与Main中不同,类中声明的是字段而不是函数. public string gender; public string name= ...
- 禁止ImageCapture自动启动
[禁止ImageCapture自动启动] 打开ImageCapture,点开左下角菜单,把Connecting this iPhone opens:的内容改为以下选项即可.
- Java中的几种设计模式
如果从事JAVA相关的开发,都不可避免的要用到抽象和封装,这是JAVA的一个特点,同时也是每个开发者必须掌握的,JAVA是这样,Android更是如此.而设计模式就是告诉我们应该如何写出高效且更具应用 ...
- ssm 动态切换数据源
1,添加数据库配置 jdbc.driver=com.microsoft.sqlserver.jdbc.SQLServerDriver #jdbc.url=jdbc:sqlserver://192.16 ...