屬性
假如你曾經用VB6編寫過程序,那麼你應該很熟悉屬性方法纔對,所謂屬性方法其實就是特殊的類成員,它實現了對私有類域的受控訪問。在C#語言中有兩種屬性方法,其一是get,通過它可以返回私有域的值,其二是set,通過它就可以設置私有域的值。比如說,以下面的代碼爲例,其間創建了一個FirstName屬性,由它控制對私有類成員firstname的訪問:
class Person { private string firstname; public string FirstName { get {return firstname;} set {firstname = value;} } } 屬性聲明可以如下編碼: Person p = new Person(); p.FirstName = "Lamont"; Console.WriteLine (p.FirstName); |
如你你所看到的那樣,屬性聲明倒更像是域聲明,只不過它還聲明瞭兩個特殊的成員,按照微軟的說法就是所謂的訪問函數(accessor)。當某一表達式的右邊調用屬性或者屬性用作其他子程序(或者函數)的參數時即會調用get訪問函數。反之,當表達式左邊調用屬性並且通過隱式傳遞value參數設置私有域值的情況下就會調用set訪問函數。你可以創建只讀屬性,方法是省略set訪問函數,這樣任何設置屬性的嘗試都會產生編譯錯誤。
採用索引器的益處
說了半天咱們轉到正題上來,那麼爲什麼我要兜這個圈子呢?其實,這是因爲類的索引器非常像屬性,從代碼上看也是這樣。以下是具有索引器的類示例,通過索引器會返回一個字符串:
class Sample { public string this [int index] { get {return "You passed " + index; } } } |
注意,這裏的屬性名是this,意思是回引類的當前實例,參數列表包含在方括號而非括號之內。還有,這是一個只讀索引器。爲了把它改成讀/寫類型,我又添加了一個set訪問函數。在定義索引器的時候,你不一定只採用一個參數。索引器參數可以採用任何類型,不過int是通常採用也是最爲合理的類型。同一類中還可能擁有一個以上的索引器(重載)。
如上定義了Sample類之後,我們就可以把索引器用作某種默認的屬性,如下所示:
Sample s = new Sample(); Console.WriteLine(s[55]); |
屬性和索引器
屬性和索引器之間有好些差別:
類的每一個屬性都必須擁有唯一的名稱,而類裏定義的每一個索引器都必須擁有唯一的簽名(signature)或者參數列表(這樣就可以實現索引器重載)。
屬性可以是static(靜態的)而索引器則必須是實例成員。
爲索引器定義的訪問函數可以訪問傳遞給索引器的參數,而屬性訪問函數則沒有參數。
接口
類似數組的行爲常受到程序實現者的喜愛,所以你還可以爲接口定義索引器,IList和 IDictionary集合接口都聲明瞭索引器以便訪問其存儲的項目。
在爲接口聲明索引器的時候,記住聲明只是表示索引器的存在。你只需要提供恰當的訪問函數即可,不必包括範圍修飾符。以下代碼把索引器聲明爲接口IImplementMe的一部分:
interface IImplementMe { string this[int index] { get; set; } |
相應實現的類則必須爲IimplementMe的索引器具體定義get和set訪問函數。
以上就是有關索引器的一些基本概述了。現在你應該對索引器在你的開發中所具有的作用有了較深入的瞭解。
索引器
C#通過提供索引器,可以象處理數組一樣處理對象。特別是屬性,每一個元素都以一個get或set方法暴露。
public class Skyscraper
{
Story[] stories;
public Story this [int index]
{
get
{
return stories [index];
}
set
{
if (value != null)
{
stories [index] = value;
}
}
}
//...
}
Skyscraper empireState = new Skyscraper (/*...*/);
empireState [102] = new Story ("The Top One", /*...*/);
【譯註:索引器最大的好處是使代碼看上去更自然,更符合實際的思考模式】