標籤:style blog http ar color os sp for on
1.索引器概述
c#中的索引器提供了文法的簡潔方便的特性,它允許你訪問對象元素如同訪問數組那樣,通常我們會在實現索引器的類的內部維護一個內部的集合或數組,通過索引器來實現對集合中的元素的存取操作。例如,我定義了一個row對象,內部維護了column數組,我們訪問通過數組的方式訪問row就相當於訪問了對應的column元素,一目瞭然。代碼如下:
public class Row { private string[] _column; public int Age { get; set; } public Row(int len) { _column = new string[len]; } public string this[int index] { get { return _column[index]; } set { _column[index] = value; } } }//測試代碼: class Program { static void Main(string[] args) { Row r = new Row(10); for (int i = 0; i < 10; i++) { r[i] = i.ToString(); } for (int i = 0; i < 10; i++) { Console.WriteLine("row["+i+"]="+r[i]); } } }
程式啟動並執行結果:
2.索引器的背後機制:
通過上面的代碼的例子我們需要知道訪問row[0]是究竟編譯器幫我們在背後做了什麼,同ildasm可以看到編譯器為我們多產生了兩個方法,一個是set_Item,一個是get_Item,如所示:
我們在看main方法產生的il中間碼如下所示:
1 .method private hidebysig static void Main(string[] args) cil managed 2 { 3 .entrypoint 4 // Code size 117 (0x75) 5 .maxstack 4 6 .locals init ([0] class Test1.Row r, 7 [1] int32 i, 8 [2] bool CS$4$0000, 9 [3] object[] CS$0$0001)10 IL_0000: nop11 IL_0001: ldc.i4.s 1012 IL_0003: newobj instance void Test1.Row::.ctor(int32)13 IL_0008: stloc.014 IL_0009: ldc.i4.015 IL_000a: stloc.116 IL_000b: br.s IL_002217 IL_000d: nop18 IL_000e: ldloc.019 IL_000f: ldloc.120 IL_0010: ldloca.s i21 IL_0012: call instance string [mscorlib]System.Int32::ToString()22 IL_0017: callvirt instance void Test1.Row::set_Item(int32,23 string)24 IL_001c: nop25 IL_001d: nop26 IL_001e: ldloc.127 IL_001f: ldc.i4.128 IL_0020: add29 IL_0021: stloc.130 IL_0022: ldloc.131 IL_0023: ldc.i4.s 1032 IL_0025: clt33 IL_0027: stloc.234 IL_0028: ldloc.235 IL_0029: brtrue.s IL_000d36 IL_002b: ldc.i4.037 IL_002c: stloc.138 IL_002d: br.s IL_006b39 IL_002f: nop40 IL_0030: ldc.i4.441 IL_0031: newarr [mscorlib]System.Object42 IL_0036: stloc.343 IL_0037: ldloc.344 IL_0038: ldc.i4.045 IL_0039: ldstr "row["46 IL_003e: stelem.ref47 IL_003f: ldloc.348 IL_0040: ldc.i4.149 IL_0041: ldloc.150 IL_0042: box [mscorlib]System.Int3251 IL_0047: stelem.ref52 IL_0048: ldloc.353 IL_0049: ldc.i4.254 IL_004a: ldstr "]="55 IL_004f: stelem.ref56 IL_0050: ldloc.357 IL_0051: ldc.i4.358 IL_0052: ldloc.059 IL_0053: ldloc.160 IL_0054: callvirt instance string Test1.Row::get_Item(int32)61 IL_0059: stelem.ref62 IL_005a: ldloc.363 IL_005b: call string [mscorlib]System.String::Concat(object[])64 IL_0060: call void [mscorlib]System.Console::WriteLine(string)65 IL_0065: nop66 IL_0066: nop67 IL_0067: ldloc.168 IL_0068: ldc.i4.169 IL_0069: add70 IL_006a: stloc.171 IL_006b: ldloc.172 IL_006c: ldc.i4.s 1073 IL_006e: clt74 IL_0070: stloc.275 IL_0071: ldloc.276 IL_0072: brtrue.s IL_002f77 IL_0074: ret78 } // end of method Program::Main
可以看到代碼的22行和60行分別對應的是源碼中的為row[i]賦值和取值的語句。我們不難猜測在set_Item和get_Item的代碼內部是對Row內部的字串數組_column進行操作。
從中我們可以總結出,索引器的背後原理實際是調用了對象的set方法和get方法,這就是索引器為我們帶來的便利性,簡化了我們變成的方式。
c# 索引器