示例文件
請(qǐng)參見“索引器”示例以下載和生成本教程中討論的示例文件。
教程
定義“索引器”使您可以創(chuàng)建作為“虛擬數(shù)組”的類。該類的實(shí)例可以使用 [] 數(shù)組訪問運(yùn)算符進(jìn)行訪問。在 C# 中定義索引器類似于在 C++ 中定義運(yùn)算符 [],但前者靈活得多。對(duì)于封裝類似數(shù)組的功能或類似集合的功能的類,使用索引器使該類的用戶可以使用數(shù)組語(yǔ)法訪問該類。
例如,假定您想定義一個(gè)類,該類使文件顯示為字節(jié)數(shù)組。如果文件非常大,則將整個(gè)文件讀入內(nèi)存是不切實(shí)際的,尤其在您只想讀取或更改少數(shù)字節(jié)時(shí)。通過定義 FileByteArray 類,您可使文件外觀類似于字節(jié)數(shù)組,但讀或?qū)懽止?jié)時(shí),實(shí)際執(zhí)行的是文件的輸入和輸出。
除下面的示例以外,本教程中還討論有關(guān)“創(chuàng)建索引屬性”的高級(jí)主題。
示例
本示例中,F(xiàn)ileByteArray 類使得像字節(jié)數(shù)組那樣訪問文件成為可能。Reverse 類反轉(zhuǎn)文件的字節(jié)。可以運(yùn)行該程序以反轉(zhuǎn)任何文本文件的字節(jié),包括程序源文件本身。若要將反轉(zhuǎn)的文件更改回正常狀態(tài),請(qǐng)?jiān)谕晃募显俅芜\(yùn)行該程序。
// indexer.cs // arguments: indexer.txt using System; using System.IO; // Class to provide access to a large file // as if it were a byte array. public class FileByteArray { Stream stream; // Holds the underlying stream // used to access the file. // Create a new FileByteArray encapsulating a particular file. public FileByteArray(string fileName) { stream = new FileStream(fileName, FileMode.Open); } // Close the stream. This should be the last thing done // when you are finished. public void Close() { stream.Close(); stream = null; } // Indexer to provide read/write access to the file. public byte this[long index] // long is a 64-bit integer { // Read one byte at offset index and return it. get { byte[] buffer = new byte[1]; stream.Seek(index, SeekOrigin.Begin); stream.Read(buffer, 0, 1); return buffer[0]; } // Write one byte at offset index and return it. set { byte[] buffer = new byte[1] {value}; stream.Seek(index, SeekOrigin.Begin); stream.Write(buffer, 0, 1); } } // Get the total length of the file. public long Length { get { return stream.Seek(0, SeekOrigin.End); } } } // Demonstrate the FileByteArray class. // Reverses the bytes in a file. public class Reverse { public static void Main(String[] args) { // Check for arguments. if (args.Length == 0) { Console.WriteLine("indexer <filename>"); return; } FileByteArray file = new FileByteArray(args[0]); long len = file.Length; // Swap bytes in the file to reverse it. for (long i = 0; i < len / 2; ++i) { byte t; // Note that indexing the "file" variable invokes the // indexer on the FileByteStream class, which reads // and writes the bytes in the file. t = file[i]; file[i] = file[len - i - 1]; file[len - i - 1] = t; } file.Close(); } }
輸入:indexer.txt
若要測(cè)試程序,可使用具有以下內(nèi)容的文本文件(該文件在“索引器”示例中稱為 Test.txt
)。
public class Hello1 { public static void Main() { System.Console.WriteLine("Hello, World!"); } }
若要反轉(zhuǎn)該文件的字節(jié),請(qǐng)編譯程序,然后使用下面的命令行:
indexer indexer.txt
若要顯示反轉(zhuǎn)的文件,請(qǐng)輸入命令:
Type indexer.txt
示例輸出
} } ;)"!dlroW ,olleH"(eniLetirW.elosnoC.metsyS { )(niaM diov citats cilbup { 1olleH ssalc cilbup
代碼討論
- 由于索引器是使用 [] 運(yùn)算符進(jìn)行訪問的,因此沒有名稱。有關(guān)索引器聲明語(yǔ)法,請(qǐng)參見索引器。
- 在上面的示例中,索引器類型是 byte,并采用 long(64 位整數(shù))類型的單個(gè)索引。“獲取”(Get) 訪問器定義從文件讀取一個(gè)字節(jié)的代碼,而“設(shè)置”(Set) 訪問器定義向文件寫入一個(gè)字節(jié)的代碼。在“設(shè)置”(Set) 訪問器內(nèi),預(yù)定義的參數(shù)值為正賦給虛擬數(shù)組元素的值。
- 索引器必須至少有一個(gè)參數(shù)。盡管相當(dāng)少見,但索引器可以有多個(gè)參數(shù),以模擬多維“虛擬數(shù)組”。盡管整數(shù)參數(shù)最常見,但索引器參數(shù)可以為任何類型。例如,標(biāo)準(zhǔn)的“字典”(Dictionary) 類提供參數(shù)類型為 Object 的索引器。
- 盡管索引器功能強(qiáng)大,但有一點(diǎn)很重要,僅當(dāng)類似數(shù)組的抽象化有意義時(shí)才使用索引器。始終應(yīng)仔細(xì)考慮使用常規(guī)方法是否會(huì)同樣清楚。例如,下面是使用索引器不當(dāng)?shù)睦樱?
class Employee { // VERY BAD STYLE: using an indexer to access // the salary of an employee. public double this[int year] { get { // return employee's salary for a given year. } } }
盡管合法,但只有“獲取”(Get) 訪問器的索引器通常不是很好的結(jié)構(gòu)。在此情況下,強(qiáng)烈建議考慮使用方法。
-
索引器可以重載(有關(guān)更多信息,請(qǐng)參見 10.8.1 索引器重載)。