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. [python] Pythonic语法笔记

    Pythonic语法笔记 __new__ 在类实例化之前执行的,也就是在init之前执行,可以为这个类写操作.接受的参数不是self而是cls.只有在new方法里返回类才会执行init操作,需要返回父 ...

  2. Vue知识整理11:列表渲染(v-for来实现)

    简单的v-for结构显示迭代数据 通过value别名 显示下面各个属性值 通过index 和key获取同类数组索引,或者不同属性的key属性名

  3. ApplicationSettingsBase运用

    先建一个类继承于ApplicationSettingsBase using System; using System.ComponentModel; namespace Concert.Configu ...

  4. ActionList及Action使用

    ActionList及Action使用 https://blog.csdn.net/adamrao/article/details/7450889 2012年04月11日 19:09:27 阅读数:1 ...

  5. zabbix添加主机后无法显示解决

    第一次添加主机后显示正常,后来删除了主机,重新添加了一下主机再也无法显示主机,很苦恼,原来需要点击重设,

  6. HTML5——添加新元素 新元素 Canvas SVG MathML 黑客帝国特效

    为HTML添加新元素 添加新元素   +   该元素定义样式 <!DOCTYPE html> <html> <head> <meta charset=&quo ...

  7. Android - Unable to add window android.view.ViewRootImpl$W@6518342 -- permission denied for window type 2133

    因为跟博主碰到了一样的问题,所以记录一下分析原理 原文链接:https://www.jianshu.com/p/b0364074288a 首先,先介绍下背景环境,第一,是Android7.0,其次,要 ...

  8. Linux window 安装tomcat各版本下载地址

    1.地址 https://mirrors.tuna.tsinghua.edu.cn/apache/tomcat/

  9. Canvas入门07- 自定义实现虚线的绘制

    预备知识 直线的斜率 一条直线与某平面直角坐标系x轴正半轴方向的夹角的正切值即该直线相对于该坐标系的斜率. 对于一条直线 y = kx +b,k就是直线的斜率. 斜率的计算 对于一条已知的线段,求斜率 ...

  10. C#打印条码BarTender SDK打印之路和离开之路(web平凡之路)(转)

    C#打印条码BarTender SDK打印之路和离开之路(web平凡之路) 从来没想过自己会写一篇博客,鉴于这次从未知的探索到一个个难点的攻破再到顺利打印,很想记录这些点滴,让后人少走弯路. 下面走进 ...