您的位置:首页 > 编程语言 > C#

结束C#2的讲解:最后的一些特性

2016-01-29 15:45 155 查看
分部类型
可以在多个源文件中为一个类型编写代码。特别适合用于部分代码是自动生成,而其他部分的代码为手动类型。
多个源代码文件组成的类型为分部类型

#region7-1演示分部类型的混合声明

partialclassExample<TFirst,TSecond>:IEquatable<string>whereTFirst:class//接口和类型的参数约束,如果实现基类,则必须为EventArgs

{

publicboolEquals(stringother)//实现IEquatable<string>

{

returnfalse;

}

}


partialclassExample<TFirst,TSecond>:EventArgs,IDisposable//指定基类和接口,不能进行参数约束

{


publicvoidDispose()//实现IDisposable

{

}

}

#endregion


分部类型还有一种不同用法:辅助进行重构,一个类型变得太大,担当太多职责,就对其进行重构。第一步,把臃肿的类型分为较小的类,接着在文件之间移动方法直到每个文件只处理一种特定的内容。

还有一个用途:单元测试。使用分部类型将测试划分为多个易于理解的小块。
C#中独有的分部方法

#region7-2分部方法在构造函数中被调用

partialclassPartialMethodDemo

{

publicPartialMethodDemo()

{

OnConstructorStart();

Console.WriteLine("Generatedconstructor");

OnConstructorEnd();

}

partialvoidOnConstructorStart();//方法没有实现,将被移除,IL中不存在

partialvoidOnConstructorEnd();//分部方法和抽象方法相同:只使用partial修饰符提供签名无需实现

}


partialclassPartialMethodDemo

{

partialvoidOnConstructorEnd()//实际实现需要partial,返回类型必须是void,不能获取out参数,它们是私有的

{

Console.WriteLine("Manualcode");

}

}

#endregion


静态类型

对工具类进行整理,以便编译器能明白你是否在不恰当的使用它们,并使你的意图更明显。

工具类的主要特征

所有成员都是静态的(除了使用构造函数)

类直接从object派生

一般情况下不应该有状态,除非涉及高速缓存或单例

不能存在任何构造函数

类可以是密封的

C#1的工具类

#region7-3典型的C#1工具类

publicsealedclassNonStaticStringHelper//密封类防止派生

{

privateNonStaticStringHelper()//提供一个私有的构造函数,防止其他代码对其进行实例化

{}


publicstaticstringReverse(stringinput)//所有方法都是静态的

{

char[]chars=input.ToCharArray();

Array.Reverse(chars);

returnnewstring(chars);

}

}

#endregion


将工具类转换为C#2静态类

#region7-4将代码7-3中的工具类转化为一个C#2的静态类

publicstaticclassStringHelper

{

publicstaticstringReverse(stringinput)

{

char[]chars=input.ToCharArray();

Array.Reverse(chars);

returnnewstring(chars);

}

}

#endregion


C#2中编译器在静态类定义上执行了大量约束:

类不能声明为abstract或sealed

类不能设定任何要实现的接口

类不能设定基类

类不能包含任何非静态成员,包括构造函数

类不能包含任何操作符

类不能包含任何protected或protectedinternal成员

独立的取值方法/赋值方法属性访问器

公有取值方法和私用赋值方法

命名空间别名

在类型名称不唯一情况下的一种决解方法。

命名空间的主要意图是将众多类型组织成一个有用的层级
using指令能够用于两种情况
一种是为命名空间和类型创建一个别名(例如:usingout=System.Console;)
另一种就是将一个命名空间引入到编译器查找的某个类型(例如:usingSystem。IO;)时可以搜索的上下文列表中。

usingWinForms=System.Windows.Forms;


namespace第七章结束Csheep2的讲解最后一些特性窗体

{

classWinForms{};//名字同为WinForms

publicpartialclassForm1:Form

{

publicForm1()

{

InitializeComponent();

Types2=typeof(WinForms::Button);//使用::告知编译器WinForms仍然做别名使用

}

}

}


全局命名空间别名

classConfiguration{}

namespace第七章结束Csheep2的讲解最后一些特性

{


classProgram

{

classConfiguration{}

staticvoidMain(string[]args)

{

#region7-7使用全局命名空间别名来准确的设定想要的类型

Console.WriteLine(typeof(Configuration));//打印:第七章结束Csheep2的讲解最后一些特性.Program+Configuration移动命名空间之前就把Configuration解析为这个类型

Console.WriteLine(typeof(global::Configuration));//打印:Configuration

Console.WriteLine(typeof(global::第七章结束Csheep2的讲解最后一些特性.Program));

#endregion

Console.ReadKey();

}

}


外部别名

你可以使用extern外部别名来指定额外信息
pragma指令

用于操作特定编译指令。

C#编译器理解的两种pragma指令:警告和校验和

#region7-9包含了未用字段的类

publicclassFieldUsedOnlyByflection

{

#region7-10禁用和恢复警告

#pragmawarningdisable0169//禁用警告

intx;

#pragmawarningrestore0169//恢复警告

#endregion

}

#endregion


非安全代码中固定大小的缓存区

在非安全代码中,可以更多的控制结构处理数组的方式

把内部成员暴露给选定的程序集
在.NET1中,内部的类型,方法,属性,变量和事件,都只能在其声明的同一个程序集中被访问,不过在.NET2中InternalsVisibleTo稍稍打破了这个规则。我们把包含这个属性的程序集称为源程序集,应用这个属性的时候,必须设定另外一个程序集,既通常所说的友元程序集。友元程序集可以看到源程序集中所有成员

[assembly:InternalsVisibleTo("FriendAssembly")]//只能用于程序集,授予FriendAssembly额外的访问权限

namespaceSource

{

#region7-12友元程序集的演示


publicclassSource1

{

internalstaticvoidInternalMethod()//在FriendAssembly可被访问

{

Console.WriteLine("InternalMethod()");

}


publicstaticvoidPublicMethod()

{

Console.WriteLine("PublicMethod()");

}

}

#endregion

}


namespaceFriendAssembly

{

publicclassClass1

{

publicvoidtest()

{

Source1.PublicMethod();

Source1.InternalMethod();

}

}

}


友元程序集让事情变得非常容易:使测试那些只能进行内部访问的代码工作,变成简单,而不用经历由于测试的目的而使成员变为公有这样不确定的步骤。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: