C# 索引器的真实用例?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2185071/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-07 00:11:08  来源:igfitidea点击:

Real world use cases for C# indexers?

c#indexer

提问by Vivek Bernard

I've seen lot of examples for c# Indexers, but in what way will it help me in real life situations.

我已经看过很多关于 c# 索引器的例子,但它在现实生活中以何种方式帮助我。

I know the C# guru wouldn't have added this if it wasn't a serious feature, but i cant think of a real world situation (not the foo bar stuff) to use indexers.

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

Note:I realize a related questionexists, but it doesn't help me much.

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

采纳答案by Rob

The way I look at indexers is that (rightly or wrongly!), accessing something by index should be more efficient than accessing it any other way, because in some way, shape or form, the class whose indexer I'm using stores some form of indexthat allows it to quickly lookup values when accessed that way.

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

The classic example is an array, when you access element n of an array by using the code myarray[3], the compiler/interpreter knows how big (memory-wise) elements of the array are and can treat it as an offset from the start of the array. You could also "for(int i = 0; i < myarray.length; i++) { if (i = 3) then { .. do stuff } }"(not that you'd ever want to!), which would be less efficient. It also shows how an array is a bad example.

经典示例是数组,当您使用代码 myarray[3] 访问数组的元素 n 时,编译器/解释器知道数组的(内存方面)元素有多大,并且可以将其视为与数组的偏移量数组的开始。你也可以"for(int i = 0; i < myarray.length; i++) { if (i = 3) then { .. do stuff } }"(不是你想要的!),这会降低效率。它还显示了数组是一个不好的例子。

Say you had a collection class that stores, umm, DVDs, so:

假设您有一个收藏类,用于存储、嗯、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];
    }
}

Just my 2p, but, like I said,.. I've always considered an "indexer" as being an expedient way of getting data out of something.

只是我的 2p,但是,就像我说的,.. 我一直认为“索引器”是从某物中获取数据的一种权宜之计。

回答by scottm

Let's say you have a collection of objects that you want to be able to index by something other than the order in which it was placed in a collection. In the example below, you can see how you could use the 'Location' property of some object and using the indexer, return all objects in the collection that match you location, or in the second example, all objects that contain a certain Count() of objects.

假设您有一个对象集合,您希望能够根据它在集合中的放置顺序以外的其他内容进行索引。在下面的示例中,您可以看到如何使用某个对象的“位置”属性并使用索引器,返回集合中与您的位置匹配的所有对象,或者在第二个示例中,所有包含特定 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);}
  }
}

回答by Daniel Pratt

Once .NET got generics, the biggest reason for me to implement an indexer (to implement a strongly-typed collection) went away.

一旦 .NET 有了泛型,我实现索引器(实现强类型集合)的最大原因就消失了。

回答by Robert Harvey

Microsoft has an exampleusing an indexer to treat a file as an array of bytes.

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);
    }
}

回答by Stefan Steinegger

It is just syntactical sugar for collection type classes. I never had a reason to write such a class. So I think there are very rare uses of it in "real life", because the classes using it are already implemented.

它只是集合类型类的语法糖。我从来没有理由写这样一门课。所以我认为它在“现实生活”中的使用非常罕见,因为使用它的类已经实现了。

回答by Jon Skeet

The most obvious examples, as mentioned by Skurmedel, are List<T>and Dictionary<TKey, TValue>. What would you prefer over:

正如 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

? Now it may be relatively rare for you need to writean indexer (usually when you're creating a collection-like class), but I suspect you usethem reasonably frequently.

? 现在,您需要编写索引器的情况可能相对较少(通常在您创建类似集合的类时),但我怀疑您使用它们的频率相当高。

回答by JB King

In ASP.Net, there are a few different times where an indexer is used such as reading something from any of the Request, Session or Application objects. I've seen often where something is stored in either the Session or Application object only to be used again and again.

在 ASP.Net 中,有时会使用索引器,例如从请求、会话或应用程序对象中的任何一个读取内容。我经常看到某些东西存储在 Session 或 Application 对象中,只是为了一次又一次地使用。

回答by Pranaya

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();
        }
    }
}

回答by code-kings

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

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

Indexers are elements in a C# program that allow a Class to behave as an Array. You would be able to use the entire class as an array. In this array you can store any type of variables. The variables are stored at a separate location but addressed by the class name itself. Creating indexers for Integers, Strings, Boolean etc. would be a feasible idea. These indexers would effectively act on objects of the class.

索引器是 C# 程序中的元素,允许类作为数组运行。您可以将整个类用作数组。在这个数组中,您可以存储任何类型的变量。变量存储在单独的位置,但由类名本身寻址。为整数、字符串、布尔值等创建索引器将是一个可行的想法。这些索引器将有效地作用于类的对象。

Lets suppose you have created a class indexer that stores the roll number of a student in a class. Further, lets suppose that you have created an object of this class named obj1. When you say obj1[0], you are referring to the first student on roll. Likewise obj1[1] refers to the 2nd student on roll.

假设您创建了一个班级索引器,用于存储班级学生的卷号。此外,假设您已经创建了一个名为 obj1 的此类对象。当您说 obj1[0] 时,您指的是第一个学生。同样 obj1[1] 指的是第二名学生。

Therefore the object takes indexed values to refer to the Integer variable that is privately or publicly stored in the class. Suppose you did not have this facility then you would probably refer in this way(which would be longer):

因此,该对象采用索引值来引用私有或公开存储在类中的 Integer 变量。假设你没有这个设施,那么你可能会以这种方式引用(这会更长):

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

where RollNumberVariable would be the Integer variable that refers to the Roll Number of the current student object.

其中 RollNumberVariable 是指当前学生对象的 Roll Number 的 Integer 变量。

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

更多详情http://code-kings.blogspot.in/2012/09/indexers-in-c-5.html

回答by code-kings

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

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

using System;

使用系统;

namespace 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;
        }
    }
}

}

}