C#索引器的真实世界用例?

我已经看到了很多c#索引器的例子,但在现实生活中它将以什么方式帮助我。

我知道C#大师不会添加这个,如果它不是一个严重的function,但我不能想到一个真实世界的情况下(而不是foo酒吧的东西)使用索引。

注意:我意识到存在一个相关的问题 ,但是对我没有多大帮助。

我看索引器的方式是(正确或错误!),通过索引访问某个东西应该比以任何其他方式访问它更有效率,因为在某种程度上,形状或forms,我正在使用的索引器的类存储某种forms的索引 ,可以在访问时快速查找值。

经典的例子是一个数组,当你通过使用代码myarray [3]来访问一个数组的元素n时,编译器/解释器知道该数组有多大(明显的)元素,并且可以把它作为数组的开始。 你也可以"for(int i = 0; i < myarray.length; i++) { if (i = 3) then { .. do stuff } }" (不是你想要的!),这将是效率较低。 它也显示了一个数组是一个坏例子。

假设你有一个collections类,可以储存,嗯,DVD,所以:

 public class DVDCollection { private Dictionary<string, DVD> store = null; private Dictionary<ProductId, string> dvdsByProductId = null; public DVDCollection() { // gets DVD data from somewhere and stores it *by* TITLE in "store" // stores a lookup set of DVD ProductId's and names in "dvdsByProductid" store = new Dictionary<string, DVD>(); dvdsByProductId = new Dictionary<ProductId, string>(); } // Get the DVD concerned, using an index, by product Id public DVD this[ProductId index] { var title = dvdsByProductId[index]; return store[title]; } } 

只是我的2p,但就像我说的,我一直认为“索引器”是从数据中获取数据的一种方便的方式。

Skurmedel提到的最明显的例子是List<T>Dictionary<TKey, TValue> 。 你更喜欢什么:

 List<string> list = new List<string> { "a", "b", "c" }; string value = list[1]; // This is using an indexer Dictionary<string, string> dictionary = new Dictionary<string, string> { { "foo", "bar" }, { "x", "y" } }; string value = dictionary["x"]; // This is using an indexer 

? 现在编写一个索引器(通常是在创build一个类似集合类的时候)可能比较less见,但是我怀疑你经常使用它们。

Microsoft 有一个使用索引器将文件视为字节数组的示例 。

 public byte this[long index] { // 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); } } 

比方说,你有一个对象的集合,你希望能够通过不同的顺序来放置在一个集合中。 在下面的示例中,您可以看到如何使用某个对象的“Location”属性并使用索引器,返回与您的位置匹配的集合中的所有对象,或者在第二个示例中,包含某个Count( )的对象。

 class MyCollection { public IEnumerable<MyObject> this[string indexer] { get{ return this.Where(p => p.Location == indexer); } } public IEnumerable<MyObject> this[int size] { get{ return this.Where(p => p.Count() == size);} } } 

一旦.NET得到了generics,我实现一个索引器(实现强types集合)的最大原因就消失了。

它只是集合types的语法糖 。 我从来没有理由写这样的课。 所以我觉得在“现实生活”中有很less的用处,因为使用它的类已经被实现了。

在ASP.Net中,有几个不同的时间使用索引器,例如从Request,Session或Application对象中读取某些内容。 我经常看到Session或Application对象中存储的内容只能被一次又一次地使用。

 using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace IndexerSample { class FailSoftArray { int[] a; // reference to underlying array public int Length; // Length is public public bool ErrFlag; // indicates outcome of last operation // Construct array given its size. public FailSoftArray(int size) { a = new int[size]; Length = size; } // This is the indexer for FailSoftArray. public int this[int index] { // This is the get accessor. get { if (ok(index)) { ErrFlag = false; return a[index]; } else { ErrFlag = true; return 0; } } // This is the set accessor. set { if (ok(index)) { a[index] = value; ErrFlag = false; } else ErrFlag = true; } } // Return true if index is within bounds. private bool ok(int index) { if (index >= 0 & index < Length) return true; return false; } } class Program { static void Main(string[] args) { FailSoftArray fs = new FailSoftArray(5); int x; // Show quiet failures. Console.WriteLine("Fail quietly."); for (int i = 0; i < (fs.Length * 2); i++) fs[i] = i * 10; for (int i = 0; i < (fs.Length * 2); i++) { x = fs[i]; if (x != -1) Console.Write(x + " "); } Console.WriteLine(); // Now, display failures. Console.WriteLine("\nFail with error reports."); for (int i = 0; i < (fs.Length * 2); i++) { fs[i] = i * 10; if (fs.ErrFlag) Console.WriteLine("fs[" + i + "] out-of-bounds"); } for (int i = 0; i < (fs.Length * 2); i++) { x = fs[i]; if (!fs.ErrFlag) Console.Write(x + " "); else Console.WriteLine("fs[" + i + "] out-of-bounds"); } Console.ReadLine(); } } } 

http://code-kings.blogspot.in/2012/09/indexers-in-c-5.html

索引器是C#程序中的一个元素,它允许一个类performance为一个数组。 你将能够使用整个类作为一个数组。 在这个数组中,你可以存储任何types的variables。 variables存储在一个单独的位置,但类名称本身。 为整数,string,布尔等创build索引器将是一个可行的想法。 这些指数将有效地对class级的对象行事。

让我们假设你已经创build了一个类索引器来存储学生在一个类中的编号。 此外,假设您已经创build了一个名为obj1的类的对象。 当你说obj1 [0]时,你指的是第一名学生。 同样,obj1 [1]是指第二名学生在滚动。

因此,对象需要索引值来引用私有或公共存储在类中的Integervariables。 假设你没有这个设施,那么你可能会这样引用(这将会更长):

 obj1.RollNumberVariable[0] obj1.RollNumberVariable[1]. 

其中RollNumberVariable将是引用当前学生对象的卷号的整数variables。

有关更多详情,请访问http://code-kings.blogspot.in/2012/09/indexers-in-c-5.html

下面我创build了一个videohttp://www.youtube.com/watch?v=HdtEQqu0yOY和下面是关于相同的详细解释。

索引器使用简化的界面帮助访问包含在集合中的集合。 这是一个句法糖。

例如让我们说你有一个客户类与地址集合里面。 现在让我们说我们想通过“Pincode”和“PhoneNumber”来获取地址集合。 所以合乎逻辑的步骤是,你将去创build两个重载函数,一个通过使用“PhoneNumber”而另一个通过“PinCode”获取。 你可以在下面的代码中看到我们定义了两个函数。

 Customer Customers = new Customer(); Customers.getAddress(1001); Customers.getAddress("9090"); 

如果你使用索引器,你可以简化上面的代码,如下面的代码所示。

 Customer Customers = new Customer(); Address o = Customers[10001]; o = Customers["4320948"]; 

干杯。

http://code-kings.blogspot.in/2012/09/indexers-in-c-5.html

使用系统;

命名空间Indexers_Example

{

 class Indexers { private Int16[] RollNumberVariable; public Indexers(Int16 size) { RollNumberVariable = new Int16[size]; for (int i = 0; i < size; i++) { RollNumberVariable[i] = 0; } } public Int16 this[int pos] { get { return RollNumberVariable[pos]; } set { RollNumberVariable[pos] = value; } } } 

}

除了@代码国王后。

此外,调用RollNumberVariable[0]将触发默认集合的索引器的行为。 虽然索引器实际上是属性 ,但是在您提取数据时,您还是要编写自己的逻辑。 您可以轻松地将大部分索引参数值委托给内部集合,但您也可以为某些索引值返回任意值。

只是一个例子 – 你可以有不同格式的2+内部集合,但是外部用户将通过一个索引器(这将作为调度器工作)与它们交互,而这些集合将被隐藏起来。 这非常鼓励封装原则。

我正在尝试从序列文件中获取图像。 我需要某种二维数组或锯齿arrays来保存像素值。 我使用索引器而不是数组,因为在索引器上循环比在二维或锯齿形数组上循环更快。

您可以使用索引器来优雅地将读/写multithreading同步提供给非线程安全的字典(或任何非线程安全的集合):

 internal class ThreadSafeIndexerClass { public object this[int key] { get { // Aquire returns IDisposable and does Enter() Exit() on a certain ReaderWriterLockSlim instance using (_readLock.Aquire()) { object subset; _dictionary.TryGetValue(key, out foundValue); return foundValue; } } set { // Aquire returns IDisposable and does Enter() Exit() on a certain ReaderWriterLockSlim instance using (_writeLock.Aquire()) _dictionary[key] = value; } } } 

特别是当你不想使用重量级的ConcurrentDictionary(或任何其他并发集合)时尤其有用。