C# 2.0 可以将类、结构或接口的定义拆分到两个或多个源文件中,在类声明前添加partial关键字即可。

例如:下面的PartialTest类

class PartialTest
{
  string Str_FieldTest;
  int Int_FieldTest;
  public void DoTest()
  {
    Debug.Print("Test");
  }
}

可在不同源文件中写成下面形式:

一个文件中写:

partial class PartialTest
{
string Str_FieldTest;
int Int_FieldTest;
}

  

另一个文件中写:

partial class PartialTest
{
public void DoTest()
{
Debug.Print("Test");
}
}

(一)什么情况下使用分部类?

–处理大型项目时,使一个类分布于多个独立文件中可以让多位程序员同时对该类进行处理(相当于支持并行处理,很实用);

–使用自动生成的源时,无需重新创建源文件便可将代码添加到类中。Visual Studio 在创建Windows 窗体、Web 窗体时都使用此方法。你不用编辑Visual Studio 所创建的文件,便可创建使用这些类的代码。换句话说:系统会自动创建一个文件(一般记录的是窗体及窗体中的控件的属性),另一个或几个文件记录的是用户自己编写的代码。这两部分分开可以使结构显得非常清晰,用户只需关注自己负责的那部分就行了(需要的话,这两部分可以互相调用)。等到了编辑运行的时候,系统会自动将这两部分合成一个文件。

(二)使用Partial需要注意以下一些情况

1.使用partial 关键字表明可在命名空间内定义该类、结构或接口的其他部分

2.所有部分都必须使用partial 关键字

3.各个部分必须具有相同的可访问性,如public、private 等

4.如果将任意部分声明为抽象的,则整个类型都被视为抽象的

5.如果将任意部分声明为密封的,则整个类型都被视为密封的

6.如果任意部分声明继承基类时,则整个类型都将继承该类

7.各个部分可以指定不同的基接口,最终类型将实现所有分部声明所列出的全部接口

8.在某一分部定义中声明的任何类、结构或接口成员可供所有其他部分使用

9.嵌套类型可以是分部的,即使它们所嵌套于的类型本身并不是分部的也如此。如下所示:

class Container
{
partial class Nested
{
void Test1();
}
partial class Nested
{
void Test2();
}
}

(三)使用分布类的一些限制

1.要作为同一类型的各个部分的所有分部类型定义都必须使用partial 进行修饰。如下所示:

public partial class A { }
public class A { } // Error, must also be marked partial

2. partial 修饰符只能出现在紧靠关键字class、struct 或interface前面的位置(枚举或其它类型都不能使用partial);

3. 要成为同一类型的各个部分的所有分部类型定义都必须在同一程序集和同一模块(.exe 或.dll 文件)中进行定义。分部定义不能跨越多个模块;

4. 类名和泛型类型参数在所有的分部类型定义中都必须匹配。泛型类型可以是分部的。每个分部声明都必须以相同的顺序使用相同的参数名。

partial class扩展功能新思路

开闭原则:“对修改封闭,对扩展开放”。在面向对象的系统中,通过类的继承实现扩展。.net中提供的partial class提供了扩展类的新思路。

一、应用场景

可以使用partial class的场景很多。这里分析一个ORM的例子。

系统中有一个Cat类,属性ID、Age、Weight都需要存储到数据库中,一个信息系统中常见的需求。通过读取数据库的结构,可以用工具生成Cat类的代码。并且ORM框架支持了从数据库信息生成Cat对象。

现在的Cat什么动作都没有,客户说,我们需要一个Miaow()的函数。这时就需要对ORM生成的Cat类进行扩展了。

可以肯定地一点是,我们不能修改自动生成的代码,因为这会牵涉到数据库结构与代码同步的问题。解决这个需求有两种方法:继承方式扩展,partial class扩展。

二、继承方式扩展

工具自动生成一个CatBase类,这个类只有属性,嵌入到ORM框架中。既然需要扩展功能,很容易想到对这个基类继承,于是有了Cat类。Cat类如愿以偿地有了Miaow()函数。

以前系统中用的是CatBase的实例,现在创建CatBase实例的地方需要改为创建Cat的实例。这个问题让ORM框架解决吧。

客户的需求实现了,我们自己的代码生成也没有遭到破坏,任务完成。

三、partial class扩展

partial class简单地说就是可以将一个类的代码写到两个或多个代码文件中。编译器在编译的过程中将这几个文件组合起来一起编译。一个很酷的技术。

工具生成的Cat类仍然不变。既然需要增加函数,那么在新建一个代码文件,将Miaow()函数写出来就可以。需要做的仅仅是将类的声明由class改为partial class,任务完成。

四、对比分析

两种思路都可以实现需求。孰优孰劣需要仔细分析一下。

实例创建:partial class更加简洁。

系统复杂度:对于系统来说,partial class方式下只存在一个类,而继承方式有两个类。

继承逻辑:从逻辑上讲,Cat并不需要一个基类CatBase,这样做仅仅是因为在代码构建过程中的一个限制。

维护性:两种方式下都会存在两个代码文件,维护成本并没有区别。

可读性:两个Cat文件确实让人费解。

整体上说,使用partial class更加优雅一些。

“继承”的这种方式比较符合传统的思维习惯,而partial class到底是不是满足开闭原则呢,这点确实不好说。不过在软件构建上,我是一个实用主义者,哪种方式好用就用哪一种。

在ORM的场景中,partial class更加好一些,但有的时候,两个类之间确实就存在继承关系,那么就必须用到继承了。虽然绝大多数情况下,都需要继承方式,但是既然有了partial class技术,我们在做设计时也需要考虑这个思路。

在VS2005中,Form、DataSet都使用了partial class方式,原理和这个一样。但是要将这个原理推广到“业务实体”中,可能在理解上需要有所突破。

使用partial class确实会带来可读性的损失,尤其是一个类分布在很多个文件中的时候,所以文件的命名最好是有一个规范来保证。

C#基础知识之Partial的更多相关文章

  1. C#基础知识之Partial class

    C# 2.0 可以将类.结构或接口的定义拆分到两个或多个源文件中,在类声明前添加partial关键字即可. 例如:下面的PartialTest类 class PartialTest { string ...

  2. [C# 基础知识系列]专题一:深入解析委托——C#中为什么要引入委托

    转自http://www.cnblogs.com/zhili/archive/2012/10/22/Delegate.html 引言: 对于一些刚接触C# 不久的朋友可能会对C#中一些基本特性理解的不 ...

  3. C# 基础知识 (三).主子对话框数值传递

    在C# winform编程中,我们经常会遇到不同窗口间需要传递数值的问题.比如数据库的应用,主窗口填写内容num1,点击按钮,在弹出的子窗口显示对应num1值;或者在子窗口填写新注册用户名信息,在主窗 ...

  4. 背水一战 Windows 10 (78) - 自定义控件: 基础知识, 依赖属性, 附加属性

    [源码下载] 背水一战 Windows 10 (78) - 自定义控件: 基础知识, 依赖属性, 附加属性 作者:webabcd 介绍背水一战 Windows 10 之 控件(自定义控件) 自定义控件 ...

  5. 背水一战 Windows 10 (76) - 控件(控件基类): Control - 基础知识, 焦点相关, 运行时获取 ControlTemplate 和 DataTemplate 中的元素

    [源码下载] 背水一战 Windows 10 (76) - 控件(控件基类): Control - 基础知识, 焦点相关, 运行时获取 ControlTemplate 和 DataTemplate 中 ...

  6. 背水一战 Windows 10 (75) - 控件(控件基类): FrameworkElement - 基础知识, 相关事件, HorizontalAlignment, VerticalAlignment

    [源码下载] 背水一战 Windows 10 (75) - 控件(控件基类): FrameworkElement - 基础知识, 相关事件, HorizontalAlignment, Vertical ...

  7. 背水一战 Windows 10 (63) - 控件(WebView): 基础知识, 加载 html, http, https, ms-appx-web:///, embedded resource, ms-appdata:///, ms-local-stream://

    [源码下载] 背水一战 Windows 10 (63) - 控件(WebView): 基础知识, 加载 html, http, https, ms-appx-web:///, embedded res ...

  8. 背水一战 Windows 10 (50) - 控件(集合类): ItemsControl - 基础知识, 数据绑定, ItemsPresenter, GridViewItemPresenter, ListViewItemPresenter

    [源码下载] 背水一战 Windows 10 (50) - 控件(集合类): ItemsControl - 基础知识, 数据绑定, ItemsPresenter, GridViewItemPresen ...

  9. 背水一战 Windows 10 (56) - 控件(集合类): ListViewBase - 基础知识, 拖动项

    [源码下载] 背水一战 Windows 10 (56) - 控件(集合类): ListViewBase - 基础知识, 拖动项 作者:webabcd 介绍背水一战 Windows 10 之 控件(集合 ...

随机推荐

  1. 在HTML标签元素中,绑定JS函数

    <a onclick="ShowMsg(this)" id="myA" href="#">按钮</a> //JS方法 ...

  2. springboot+mybatis+SpringSecurity 实现用户角色数据库管理(一)

    本文使用springboot+mybatis+SpringSecurity 实现用户权限数据库管理 实现用户和角色用数据库存储,而资源(url)和权限的对应采用硬编码配置. 也就是角色可以访问的权限通 ...

  3. leetcode-mid-math-202. Happy Number-NO

    mycode 关键不知道怎么退出循环.............其实只要有一个平方和以前出现过,那么整个计算过程就会重复 参考: class Solution(object): def isHappy( ...

  4. Mac OS 10安装CocoaPods流程

    一.简介 什么是CocoaPods CocoaPods是OS X和iOS下的一个第三类库管理工具,通过CocoaPods工具我们可以为项目添加被称为“Pods”的依赖库(这些类库必须是CocoaPod ...

  5. leetcode 240搜索二维矩阵

    /** 正常的二维搜索估计要超时,本题沿着对角线搜索,然后找到第一个大于目标数字的坐标(x,y)然后搜索(>x,<y)(<x,>y)子区域: 矩阵size() 为m,n:当i& ...

  6. Git - 对一组仓库进行配置

    对一组仓库使用一套配置,另一组仓库使用另一套配置的需求也是有的,比如公司仓库的配置和我个人项目的仓库配置并不完全相同,每次都修改单个仓库的配置太麻烦并且可能会粗心忘改了以错误的配置进行提交,如何对一个 ...

  7. 大数据时代下EDM邮件营销的变革

    根据研究,今年的EDM邮件营销的邮件发送量比去年增长了63%,许多方法可以为你收集用户数据,这些数据可以帮助企业改善自己在营销中的精准度,相关性和执行力. 最近的一项研究表明,中国800强企业当中超过 ...

  8. MYSQL5.7源码包编译安装

    Centos下用cmake编译安装MySQL 5.7安装依赖包yum -y install gcc gcc-c++ ncurses ncurses-devel cmake下载相应源码包cd /usr/ ...

  9. Selenium学习之==>WebDriver驱动对照表

    转自www.imdsx.cn 1.Chrome 对于chrome浏览器,有时候会有闪退的情况,也许是版本冲突的问题,我们要对照着这个表来对照查看是不是webdriver和chrome版本不对. chr ...

  10. C++ com 组件 事件 备忘

    [ object, uuid(AECE8D0C-F902--A374-ED3A0EBB6B49), dual, nonextensible, pointer_default(unique) ] int ...