我已经看到了很多C#索引器的例子,但是它在现实生活中有什么用途呢?
我知道如果这不是一个重要的特性,C#大师就不会添加它,但是我想不出一个实际应用场景(不是那些虚构的东西)来使用索引器。
注意:我意识到相关问题存在,但它并没有对我有太大的帮助。
我已经看到了很多C#索引器的例子,但是它在现实生活中有什么用途呢?
我知道如果这不是一个重要的特性,C#大师就不会添加它,但是我想不出一个实际应用场景(不是那些虚构的东西)来使用索引器。
注意:我意识到相关问题存在,但它并没有对我有太大的帮助。
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];
}
}
仅提供我的个人意见,但是,就像我说的那样.. 我一直认为"索引器"是从某些东西中获取数据的一种便捷方式。
正如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
? 现在你可能相对较少需要编写索引器(通常是在创建类似集合的类时),但我认为你相当频繁地使用它们。
微软提供了一个示例,使用索引器将文件视为字节数组。
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);
}
}
假设您有一组对象,想要按照某些不同于它们在集合中放置顺序的方式进行索引。在下面的示例中,您可以看到如何使用某个对象的“位置”属性,并使用索引器返回与您位置匹配的集合中的所有对象,或者在第二个示例中,返回包含特定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拥有泛型,我实现索引器(用于实现强类型集合)的最大原因就消失了。
这只是一种针对集合类型类的语法糖。我从来没有写过这样的类,因此我认为在“现实生活”中很少使用它,因为使用它的类已经被实现了。
GetElement
方法之间有什么区别吗?使用索引器更短。 - Stefan Steineggerhttp://code-kings.blogspot.in/2012/09/indexers-in-c-5.html
索引器是C#程序中的元素,允许类表现为数组。您可以使用整个类作为数组。在此数组中,您可以存储任何类型的变量。变量存储在单独的位置上,但由类名本身寻址。为整数、字符串、布尔等创建索引器是可行的想法。这些索引器将有效地作用于类的对象。
假设您已经创建了一个类索引器,用于存储班级中学生的学号。进一步假设您已经创建了一个名为obj1的此类对象。当您说obj1 [0]时,您正在引用排名第一的学生。同样,obj1 [1]指的是排名第二的学生。
因此,该对象采用索引值来引用类中私有或公共存储的整数变量。假设您没有此功能,则可能会以更长的方式引用:
obj1.RollNumberVariable[0]
obj1.RollNumberVariable[1].
RollNumberVariable是指当前学生对象的学号整数变量。
更多细节请参见http://code-kings.blogspot.in/2012/09/indexers-in-c-5.html
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();
}
}
}
您可以使用索引器来优雅地为非线程安全的字典(或任何非线程安全的集合)提供读/写多线程同步:
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(或任何其他并发集合)时,特别有用。