C# 基础系列--类一(partial 部分类和部分方法)
类,开始学面向对象的时候,我们就开始学这个。按道理来说,应该没有什么好的。其实这里面还是有很多可以挖掘的知识点。这篇重点阐述部分类partial。
部分类的关键字partial ,它只能声明在class struct,interface之前。先来个简单的例子:新建类库:AssemblyLibrary并建PulClass类文件
public partial class PulClass { public int ID { get; set; } }
这就是一个简单的部分类。你可以只有一个partial class。但是为了更好的说明这个例子。简单点,直接在下面加入下面的代码:
public partial class PulClass { public int Name { get; set; } }
我们用ILSpy来看看生成的代码是怎么样的
很简单吧。
那是不是,我们可以再不同的程序集中使用partial呢。答案是否定的。类--继承,封装,多态。试想下如果在不同的程序集中使用部分类,那么类的封装不就是打破了吗?
实验是检验真理的唯一标准。还是让vs直接告诉我们吧,新建项目ConsolTest,引用刚刚的类库AssemblyLibrary
直接报错。
那partial的适用范围是什么呢?msdn的解释:
要成为同一类型的各个部分的所有分部类型定义都必须在同一程序集和同一模块(.exe 或 .dll 文件)中进行定义。 分部定义不能跨越多个模块。
类的访问性有public,private,protect还有其他乱七八糟的修饰关键字,这些会不会影响的partial呢?我也不确定,如果不会,那么一个public和一个private,我想,编译出来应该是 private,如果有,你懂的,关键字一致,实验下。
public partial class PulClass { public int ID { get; set; } } private partial class PulClass { public int Name { get; set; } }
直接报错:错误 1 命名空间中定义的元素无法显式声明为 private、protected 或 protected internal
看来,partial不能和private和protected和protected innernal一起使用。那么类的默认的可访问性是,private,如果 我们省缺,他默认 的是什么呢?我们去掉,编译用ILSpy看下:
看来partial的默认访问是:internal。
partial类不仅仅可以对属性进行部分化处理,同样也可以对特性、方法进行部分化处理。
[ObsoleteAttribute] public partial class PulClass { public int ID { get; set; } } [Serializable] public partial class PulClass { public int Name { get; set; } }
编译出来的是
using System; namespace AssemblyLibrary { [Obsolete] [Serializable] public class PulClass { public int ID { get; set; } public int Name { get; set; } } }
接口也可以像特性一样合并。这里就不在累赘了
接口:
partial interface ITest { int ID { get; set; } } partial interface ITest { string Name { get; set; } }
编程生成的:
using System; namespace AssemblyLibrary { internal interface ITest { int ID { get; set; } string Name { get; set; } } }
部分类的最后一部分,partial方法:
方法有执行顺序,如果使用partial是什么样子的呢?
public partial class fangfa { //partial void Run() //{ // Console.WriteLine("partial Run"); //} } public partial class fangfa { protected partial void Run(); }
vs又提示我们错误了:错误 1 分部方法不能具有访问修饰符或 virtual、abstract、override、new、sealed 或 extern 修饰符
居然protected都有错误,那么public更不用说了,不信,你可以去试试
你们猜猜,如果去掉protected会是什么的结果呢?很有意思哦,我们的编译器对他进行了优化,把Run方法给去掉了
using System; namespace AssemblyLibrary { public class fangfa { } }
部分方法,必须是void 。说实话,现在我看不出来,部分方法有什么好处,部分 类在以前的代码管理器中,我们可以同时维护一个类。如果用TFS的话,部分类的用处也不大,因为TFS可以合并N个人写的代码,不过我不会设置。哈哈
对了,差点忘记了泛型类?不知道这个会是怎么样的?试试吧
[ObsoleteAttribute] public partial class PulClass<T> { public int ID { get; set; } public T Create() { return default(T); } } [Serializable] public partial class PulClass<T> { public int Name { get; set; } }
static void Main(string[] args) { PulClass<int> pu = new PulClass<int>(); pu.ID = 1; Console.WriteLine(pu.Create().ToString()); Console.Read(); }
细心的朋友,估计看到的vs报的警告,这个是使用了ObsoleteAttribute这个特性的原故。
泛型 方法也是可以部分类的,个人感觉部分方法很鸡肋,就不多说了,想知道可以自己试试。