知识在于积累。

前言

好久没写博客了,因为在看《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. C++ - 容器概述

    一 迭代器iterator 5种类别 常用的迭代器 常用的迭代器 二 分配算符Allocators 三 容器简介 STL标准容器类简介 标准容器类 说明 顺序性容器 关联容器 容器适配器 所有标准库共 ...

  2. django-DIL模板自定义过滤器,自定义标签,自定义包含标签

    自定义过滤器 DTL模板语言生来只是为了方便的展示信息,所以与编程语言相比显得有点薄弱,有时候不能满足我们的需求.因此django提供了一个接口,让开发者能自定义标签和过滤器. 首先,你需要添加一个t ...

  3. urllib2的GET和POST请求(五)

    urllib2默认只支持HTTP/HTTPS的GET和POST方法 urllib.urlencode() urllib 和 urllib2 都是接受URL请求的相关模块,但是提供了不同的功能.两个最显 ...

  4. .NET 同步 异步 委托

    1.定义委托: using System; using System.Collections.Generic; using System.IO; using System.Linq; using Sy ...

  5. 「小程序JAVA实战」小程序首页视频(49)

    转自:https://idig8.com/2018/09/21/xiaochengxujavashizhanxiaochengxushouyeshipin48/ 视频显示的内容是视频的截图,用户的头像 ...

  6. "sc.exe create/delete" - Create or Delete Services

    "sc.exe" can also be used to create and delete services. If you want to create a new servi ...

  7. NodeJs-Linux环境初步

    1.Express 是一个简洁而灵活的 node.js Web应用框架, 提供了一系列强大特性帮助你创建各种 Web 应用,和丰富的 HTTP 工具. 使用 Express 可以快速地搭建一个完整功能 ...

  8. HBase实验(CRUD和MR入库)

    目录 前期准备 在HBase shell中实现CRUD操作 1. 启动命令行客户端 2. 创建表 3. 删除.新增列族 4. 删除表teacher 5. 新增数据 6. 查看数据 用Java API实 ...

  9. 在Action中获取表单提交数据

    -----------------siwuxie095 在 Action 中获取表单提交数据 1.之前的 Web 阶段是提交表单到 Servlet,在其中使用 Request 对象 的方法获取数据 2 ...

  10. memcached的常用命令

    memcached 常用命令及使用说明   1.启动Memcache 常用参数 -p <num> 设置TCP端口号(默认设置为: 11211) -U <num> UDP监听端口 ...