深入理解C#(十四)

*第七章(C# 2:其他特性)

分部类型,静态类,独立的取值方法,命名空间别名,Pragma指令,固定大小的缓冲区,InternalsVisibleToAttribute(友元程序集)

分部类型

在多个文件中创建一个类型

创建分部类型,只需要加上partial关键字。编译器实际上是在编译之前把所有源文件合并在一起。(这就是为什么C#文件名和类名可以不一致了,同样一个class Example,可以用分部类型,写多个Example1/2/…cs文件

举例:

1
2
3
4
5
6
7
8
9
 partial class Example<TFirst, TSecond>
: IEquatable<string>
where TFirst : class
{
public bool Equals(string other)
{
return false;
}
}

在这个文件中声明接口和类型参数约束

1
2
3
4
5
6
7
 partial class Example<TFirst, TSecond>
: EventArgs, IDisposable
{
public void Dispose()
{
}
}

在这个文件中声明基类和接口

分布类型的使用

分布类型的用途:

  1. 主要联接设计器和其他代码生成器
  2. 辅助进行重构
  3. 单元测试

C# 3的分部方法

分部方法的声明与抽象方法相同:

使用partial修饰符无须实现,在实际的实现部分也要partial修饰符。

分部方法可以不被实现,这些未被实现的分部方法的调用会被编译器移除。

由于方法可能不存在,分部方法返回类型必须为void,且不能获取out参数。必须是私有的

静态类型

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

举例:

1
2
3
4
5
6
string name;
public string Name
{
get{return name;}
private set{ name=value;}
}

Name属性对于其他所有类型都是只读的,但在类型内部能用属性语法设置。

大部分的默认访问修饰符是私有的,但对于取值/赋值方法,访问修饰符和属性本身整体上保持一致

另外不能把属性设为私有,但把取值方法设为公有

命名空间别名

限定的命名控件别名

C# 1例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
using System;
using System.ComponentModel;
using WebForms = System.Web.UI.WebControls;
using WinForms = System.Windows.Forms;

namespace Chapter07
{
[Description("Listing 7.05")]
class SimpleAliases
{
static void Main()
{
Console.WriteLine (typeof (WinForms.Button));
Console.WriteLine (typeof (WebForms.Button));
}
}
}

若有一个类也叫WinForms,那编译器该如何区分?
C# 2改进:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
using System;
using System.ComponentModel;
using WebForms = System.Web.UI.WebControls;
using WinForms = System.Windows.Forms;

namespace Chapter07
{
[Description("Listing 7.06")]
class DoubleColonForAliases
{
class WinForms
{
}

static void Main()
{
Console.WriteLine (typeof (WinForms::Button));
Console.WriteLine (typeof (WebForms::Button));
}
}
}

引入“::“来区分命名空间和类型

全局命名空间别名

无法为命名空间层级的根或全局命名空间定义别名。

可以使用global::

外部别名

pragma指令

pragma指令是一个由#pragma开头的代码行所表示的预处理指令,它后面能包含任何文本。

警告pragma

举例:例如我们使用了一个从未使用的变量,但想要忽略编译器警告

1
2
3
#pragma warning disable 0169
int x;
#pragma warning restore 0169

校验和pragma

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

把内部成员暴露给选定的程序集