屬性
屬性可以說是C#語言的一個創新。當然你也可以說不是。不是的原因是它背後的實現實際上還是兩個函數--一個賦值函數(get),一個取值函數(set),這從它生成的中間語言代碼可以清晰地看到。是的原因是它的的確確在語言層面實現了面向對象編程一直以來對“屬性”這一OO風格的類的特殊接口的訴求。理解屬性的設計初衷是我們用好屬性這一工具的根本。C#不提倡將域的保護級別設為public而使用戶在類外任意操作--那樣太不OO,或者具體點說太不安全!對所有有必要在類外可見的域,C#推薦采用屬性來表達。屬性不表示存儲位置,這是屬性和域的根本性的區別。下面是一個典型的屬性設計:
using System;
class MyClass
{
int integer;
public int Integer
{
get {return integer;}
set {integer=value;}
}
}
class Test
{
public static void Main()
{
MyClass MyObject=new MyClass();
Console.Write(MyObject.Integer);
MyObject.Integer++;
Console.Write(MyObject.Integer);
}
}
一如我們期待的那樣,程序輸出0 1。我們可以看到屬性通過對方法的包裝向程序員提供了一個友好的域成員的存取界面。這裡的value是C#的關鍵字,是我們進行屬性操作時的set的隱含參數,也就是我們在執行屬性寫操作時的右值。
屬性提供了只讀(get),只寫(set),讀寫(get和 set)三種接口操作。對域的這三種操作,我們必須在同一個屬性名下聲明,而不可以將它們分離,看下面的實現:
class MyClass
{
private string name;
public string Name
{
get { return name; }
}
public string Name
{
set { name = value; }
}
}
上面這種分離Name屬性實現的方法是錯誤的!我們應該像前面的例子一樣將他們放在一起。值得注意的是三種屬性(只讀,只寫,讀寫)被C#認為是同一個屬性名,看下面的例子:
class MyClass
{
protected int num=0;
public int Num
{
set
{
num=value;
}
}
}
class MyClassDerived: MyClass
{
new public int Num
{
get
{
return num;
}
}
}
class Test
{
public static void Main()
{
MyClassDerived MyObject = new MyClassDerived();
//MyObject.Num= 1; //錯誤 !
((MyClass)MyObject).Num = 1;
}
}
我們可以看到MyClassDerived中的屬性Num-get{}屏蔽了MyClass中屬性Num-set{}的定義。