知识在于积累。

前言

好久没写博客了,因为在看《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. 「小程序JAVA实战」小程序视频组件与api介绍(51)

    转自:https://idig8.com/2018/09/22/xiaochengxujavashizhanxiaochengxushipinzujianyuapijieshao50/ 这次说下,小程 ...

  2. eclipse Android 开发基础 Activity 窗体 界面

    eclipse Android 开发基础 新建工程 新建布局layout,new Android Activity就相当于窗体Form. 新建Activity自动生成src下同名的java代码. pu ...

  3. sql server2008本地连接选择windows身份验证无法登陆的解决办法

    1.安装完sqlserver数据库,本地连接登录不了 解决办法:进入cmd,输入net start mssqlserver 服务启动后,再次用windows身份验证就可以登陆本地数据库了

  4. CentOS 多版本python安装pip

    首先配置环境 安装 zlib,zlib-devel,openssl,openssl-devel yum install zlib yum install zlib-devel yum install ...

  5. epoll用法【整理】

    l  epoll是什么? epoll是当前在Linux下开发大规模并发网络程序的热门人选,epoll 在Linux2.6内核中正式引入,和select相似,都是I/O多路复用(IO multiplex ...

  6. django 下载文件 无法正常打开

    下载文件,无法正常打开,如下图 需手动加后缀名修改文件格式方可正常打开进而能得知文件内容正常如下图,给“下载”文件加上后缀即可得到正常下载的内容 问题整理:(此下载功能采用StreamHttpResp ...

  7. HTTP请求出现405状态码method not allowed的解决办法

    httppost请求目标网站出现405状态码, 原因为 Apache.Nginx.IIS等绝大多数web服务器,都不允许静态文件响应POST请求所以将post请求改为get请求即可

  8. shell脚本学习指南-学习(2)

    1.I/O重定向符:<   >  >与管道   | #! /bin/bash echo -n "Enter your name!" //输出 printf &qu ...

  9. PHP 文件处理(综合)

    1.获取远程文件大小:php获得远程文件大小的函数php获得远程文件大小的函数文件的大小函数为:filesize()文件是否存在的函数为:file_exits();但是这两个函数只针对本地那么:远程文 ...

  10. Halcon二维仿射变换实例探究

    二维仿射变换,顾名思义就是在二维平面内,对对象进行平移.旋转.缩放等变换的行为(当然还有其他的变换,这里仅论述这三种最常见的). Halcon中进行仿射变换的常见步骤如下: ① 通过hom_mat2d ...