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. 服务器控件调用JS函数

    是服务器端控件,不能在JS里直接调用,但可以在aspx.cs 里写方法可以调用JS函数,比如JS方法名称是check(), function check() {   alert(document.ge ...

  2. Linux_ServicesManagement_RHEL7

    目录 目录 Network Manager RHEL7的服务管理systemctl指令 服务的启动停止重载重启 服务的分类 指令选项 Network Manager 注意:network servic ...

  3. webpack打包文件解析

    /** * 对于没有代码分割的,webpack会打包生成main.js一个大的自执行函数 * 函数参数是一个对象,键值分别是路径和模块的函数 * 函数内部定义了一些方法,包括__webpack_req ...

  4. 用例a失败,跳过测试用例b和c并标记失败xfail

    前言 当用例a失败的时候,如果用例b和用例c都是依赖于第一个用例的结果,那可以直接跳过用例b和c的测试,直接给他标记失败xfail用到的场景,登录是第一个用例,登录之后的操作b是第二个用例,登录之后操 ...

  5. 使用python脚本部署mariadb主从架构

    环境准备 一个脚本自动部署master服务 另一个部署slave服务 关闭主从节点的防火墙 以及事先设置好root远程登陆的权限. grant all on *.* to root@'%'  iden ...

  6. c# 跨应用程序域通讯

    public class MyTask { public class MyEventArgs : EventArgs { public object EventData { get; private ...

  7. Java ——异常处理

    本节重点思维导图 详细戳——> 异常处理

  8. 【MM系列】MB1A MB1B MB1C MB11 MIGO的区别解析

    公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[MM系列]MB1A MB1B MB1C MB1 ...

  9. pyspark的安装配置

    1.搭建基本spark+Hadoop的本地环境 https://blog.csdn.net/u011513853/article/details/52865076?tdsourcetag=s_pcqq ...

  10. angular5 给元素添加自定义属性

    今天尝试给一个a 标签添加一个自定义属性,用于存放相关数据,但是angular templates 编译不通过. <a href="javascript:void(0);" ...