什么时候应该使用 C# 索引器?

发布于 2024-09-11 13:04:52 字数 175 浏览 10 评论 0原文

我想更多地使用索引器,但我不确定何时使用它们。我在网上找到的所有示例都是使用 MyClassIndexerClass 等类的示例。

在有学生和教师的学校系统中,每个教师都有一个他们负责的学生列表,在这种情况下是否需要索引器?为简单起见:每个学生只能属于一位教师。

I'd like to use indexers more, but I'm not sure when to use them. All I've found online are examples that use classes like MyClass and IndexerClass.

What about in a school system where there are Students and Teachers, and each Teacher has a list of Students that they're in charge of - any need for indexers in that scenario? For simplicity's sake: each Student can only belong to one Teacher.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

下壹個目標 2024-09-18 13:04:52

索引器是一个高度专业化的属性,它允许像数组一样对类(或结构)的实例进行索引(属性可以是静态的,但索引器不能)。

为什么使用索引器:

  • 类本身不是一个新的数据结构,而是一个数据结构。
  • 简化的语法 - 语法糖

何时使用:

  • 如果您的类需要其实例的列表(/数组)(示例 1)
  • 如果您的类表示与您的类直接相关的值列表(/数组)(示例 2)

示例 1:

public class Person{
    public string Name{get; set;}
    
    private Person[] _backingStore;
    public Person this[int index]
    {
        get{
            return _backingStore[index];
        }
        set{
            _backingStore[index] = value;
        }
    }
}

Person p = new Person();
p[0] = new Person(){Name = "Hassan"};
p[1] = new Person(){Name = "John Skeet"};    

示例 2:

class TempratureRecord{
    private float[] temps = new float[10] { 56.2F, 56.7F, 56.5F, 56.9F, 58.8F, 61.3F, 56.5F, 56.9F, 58.8F, 61.3F};

    public int Length{
        get { return temps.Length; }
    }

    public float this[int index]
    {
        get{
            return temps[index];
        }
        set{
            temps[index] = value;
        }
    }
}

Indexer is a highly specialized property which allows instances of a class (or struct) to be indexed just like an array (properties can be static but indexers cannot).

Why to use indexers:

  • instead of a new data structure, the class itself is a data structure.
  • simplified syntax - syntactic sugar

When to use:

  • if your class needs list(/array) of its instances (example 1)
  • if your class represents list(/array) of values directly related to your class (example 2)

Example 1:

public class Person{
    public string Name{get; set;}
    
    private Person[] _backingStore;
    public Person this[int index]
    {
        get{
            return _backingStore[index];
        }
        set{
            _backingStore[index] = value;
        }
    }
}

Person p = new Person();
p[0] = new Person(){Name = "Hassan"};
p[1] = new Person(){Name = "John Skeet"};    

Example 2:

class TempratureRecord{
    private float[] temps = new float[10] { 56.2F, 56.7F, 56.5F, 56.9F, 58.8F, 61.3F, 56.5F, 56.9F, 58.8F, 61.3F};

    public int Length{
        get { return temps.Length; }
    }

    public float this[int index]
    {
        get{
            return temps[index];
        }
        set{
            temps[index] = value;
        }
    }
}
长伴 2024-09-18 13:04:52

这是我创建的视频http://www.youtube.com/watch?v=HdtEQqu0yOY 下面是关于相同内容的详细解释。

索引器有助于使用简化的接口访问类中包含的集合。这是一个语法糖。

例如,假设您有一个客户类,其中包含地址集合。现在假设我们想通过“Pincode”和“PhoneNumber”获取地址集合。因此,逻辑步骤是您将创建两个重载函数,一个使用“PhoneNumber”获取,另一个使用“PinCode”获取。您可以在下面的代码中看到我们定义了两个函数。

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

如果您使用索引器,您可以使用以下代码所示的内容来简化上述代码。

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

干杯。

Heres a video i have created http://www.youtube.com/watch?v=HdtEQqu0yOY and below is a detailed explanation about the same.

Indexers helps to access contained collection with in a class using a simplified interface. It’s a syntactic sugar.

For instance lets say you have a customer class with addresses collection inside it. Now let’s say we would like to like fetch the addresses collection by “Pincode” and “PhoneNumber”. So the logical step would be that you would go and create two overloaded functions one which fetches by using “PhoneNumber” and the other by “PinCode”. You can see in the below code we have two functions defined.

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

If you use indexer you can simplify the above code with something as shown in the below code.

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

Cheers.

冷默言语 2024-09-18 13:04:52

如果类表示对象的列表、集合或数组,则通常使用索引器。在您的情况下,您可以提供一个索引器来为教师的学生提供基于索引的访问。

You typically use an indexer if the class represents a list, collection or array of objects. In your case, you could provide an indexer to provide index-based access to a teacher's students.

心凉怎暖 2024-09-18 13:04:52

在您的情况下使用的索引器将是 TeachersClass 类,它将封装学生(集合)和当前教师。虽然您可以通过公开学生列表来执行相同的操作,但它确实向您展示了一个示例。

这是一个代码示例:

public class TeachersClass
    {
        private List<Student> _students;

        public TeachersClass(Teacher currentTeacher, List<Student> students)
        {
            CurrentTeacher = currentTeacher;
            _students = students;
        }

        public Teacher CurrentTeacher { get; set; }

        public Student this[int studentID]
        {
            get
            {
                return (from s in _students
                        where s.Id = studentID
                        select s).First();
            }
        }   
    }

An indexer use in your situation would be a TeachersClass class, which would encapsulate the students (collection) and the current teacher. Although you could do the same thing by exposing the list of students, but it does show you an example.

Here is a code example:

public class TeachersClass
    {
        private List<Student> _students;

        public TeachersClass(Teacher currentTeacher, List<Student> students)
        {
            CurrentTeacher = currentTeacher;
            _students = students;
        }

        public Teacher CurrentTeacher { get; set; }

        public Student this[int studentID]
        {
            get
            {
                return (from s in _students
                        where s.Id = studentID
                        select s).First();
            }
        }   
    }
凉月流沐 2024-09-18 13:04:52

随机顺序访问

如果您的数据通常按顺序访问,您将使用枚举器。

另一方面,索引器对于直接访问特定元素非常有用,没有特定的顺序。

当然,这假设您知道所需元素的索引。例如,组合框始终支持两个值:向用户显示的字符串以及所属的 id。您可以使用组合框中所选项目的 ID 直接访问集合的索引,而不必搜索集合。

C# 中索引器的好处是您可以重载它们,因此您可以通过不同类型的键访问项目。

Random order access

You would use an enumerator if your data is normally accessed sequentially.

An indexer on the other hand is useful for directly accessing a specific element, no specific order.

This of course assumes you know the index of the element you want. Comboboxes for example have always supported two values: the string shown to the user, and the id that belongs with it. You could use the id from a selected item in a combobox to directly access the index of your collection, instead of having to search the collection.

The nice thing about indexers in C# is that you can overload them, so you can access items through different kind of keys.

╄→承喏 2024-09-18 13:04:52

简单的答案(如上所述)是当类表示/包含项目集合时,索引器将返回集合的元素。

public Student this[int index] { ..

在更高级的情况下,您可以使用类创建默认行为,并使其看起来有点像委托,特别是当该类表示映射或进程时。例如,计算冰箱中啤酒的冷却速率的类:

无需键入内容。

temperature = coorsLight.CalculateFutureTemperature(time);

您可以将其确定为

temperature = coorsLight[time];

该类的预期行为(和意图)是否返回一个值,而

The simple answer (as stated above) is when the class represents/contains a collection of items, the indexer will return the elements of the collection.

public Student this[int index] { ..

In a more advanced case you can create a default behavior with a class and make it look a bit like a delegate, especially when the class represents a mapping, or a process. For example a class that calculates the cooling rate of a beer in the refrigerator:

Instead of typing

temperature = coorsLight.CalculateFutureTemperature(time);

you can condence this to

temperature = coorsLight[time];

if the expected behavior (and intent) of the class is to return a value.

索引器是一种从聚合(例如数组或集合)中选择元素的方法。虽然我部分同意 Ian Davis 的观点,但我认为索引器代表的不仅仅是公共 API 的完善。

索引器是访问数组和表示 .NET BCL 实现的索引器中集合的大多数主要类的主要方式,大概是为了在处理聚合其他类型的类型时提供通用的体验。

因为索引器是许多 BCL 集合类型接口的标准部分,并且因为这些类型被大量使用,所以随着开发人员学习 .NET 作为平台,有理由建议创建一个期望,即可以使用以下方式访问集合某种类型的索引器。

如果您的类型的接口符合开发人员已有的期望,那么该类型就会变得更易于使用,因为开发人员无需思考。无论相关开发人员是组织内部的还是外部的,这都是事实。

当然,在某些情况下,拥有索引器是没有意义的,如果是这种情况,那么就不要实现索引器。

An indexer is a means to select an element from an aggregate such as an array or collection. While I agree in part with Ian Davis, I think indexers represent something more than public API polish.

Indexers are the primary means of accessing arrays and most of the major classes representing collections in the .NET BCL implemented indexers, presumably to provide a common expernce when dealing with types that aggregate other types.

Because indexers are a standard part of the interface to many of the BCLs collection types, and because these types are heavily used, as developers learn .NET as a platform, it is reasonable to suggest that an expectation is created that collections can be accessed using some type of indexer.

If your type's interface matches the expectations that developers have already, then that type becomes easier to use because the developer doesn't have to think. This is true whether the developers in question are internal to your organization or out there in the wild.

Of course there are situations where having an indexer just doesn't make sense, and if thats the case then don't implement an indexer.

勿忘初心 2024-09-18 13:04:52

索引器允许像数组一样对类或结构的实例进行索引。索引器类似于属性,只是它们的访问器采用参数。

索引器允许以与数组类似的方式对对象进行索引。

    // C#: INDEXER 
using System; 
using System.Collections; 

class MyClass 
{ 
    private string []data = new string[5]; 
    public string this [int index] 
    { 
       get 
       { 
           return data[index]; 
       } 
       set 
       { 
           data[index] = value; 
       } 
    } 
}

class MyClient 
{ 
   public static void Main() 
   { 
      MyClass mc = new MyClass(); 
      mc[0] = "Rajesh"; 
      mc[1] = "A3-126"; 
      mc[2] = "Snehadara"; 
      mc[3] = "Irla"; 
      mc[4] = "Mumbai"; 
      Console.WriteLine("{0},{1},{2},{3},{4}",mc[0],mc[1],mc[2],mc[3],mc[4]); 
   } 
} 

代码项目

Indexers allow instances of a class or struct to be indexed just like arrays. Indexers resemble properties except that their accessors take parameters.

Indexers enable objects to be indexed in a similar manner to arrays.

    // C#: INDEXER 
using System; 
using System.Collections; 

class MyClass 
{ 
    private string []data = new string[5]; 
    public string this [int index] 
    { 
       get 
       { 
           return data[index]; 
       } 
       set 
       { 
           data[index] = value; 
       } 
    } 
}

class MyClient 
{ 
   public static void Main() 
   { 
      MyClass mc = new MyClass(); 
      mc[0] = "Rajesh"; 
      mc[1] = "A3-126"; 
      mc[2] = "Snehadara"; 
      mc[3] = "Irla"; 
      mc[4] = "Mumbai"; 
      Console.WriteLine("{0},{1},{2},{3},{4}",mc[0],mc[1],mc[2],mc[3],mc[4]); 
   } 
} 

Code project

与之呼应 2024-09-18 13:04:52

我记得有一次,我在课堂上有一个 long,并且该特定 long 的某些数字意味着某些东西(例如,如果第三个数字是 3,则意味着图表具有特定类型的编码,我知道可怕的系统但我没有发明它)

所以我做了类似的事情来返回数字的第x位:

protected int this[int index]
{
    get
    {
        int tempN = Number;
        if (index > 0)
        {
            tempN /= index * 10;
        }
        return tempN % 10;
    }
}

它受到保护,因为不同的方法使用了它,所以它是一种帮助器。当然,一个简单的 GetDigit(int a) 会是同样的事情(并且更不言自明),但当时我认为这是我认为使用索引器有意义的少数几次之一。自从 =( 以来就没有使用过它们。

I remember there was this time when I had a long inside a class, and some digits of that particular long meant something (for example if the third digit was a 3 it meant that the chart had a specific type of encoding, horrible system I know but I didn't invent it)

So I did something like this to return the xth digit of the number:

protected int this[int index]
{
    get
    {
        int tempN = Number;
        if (index > 0)
        {
            tempN /= index * 10;
        }
        return tempN % 10;
    }
}

It was protected because a different method used it, so it was kind of a helper. Of course a simple GetDigit(int a) would've been the same thing (and more self-explanatory) but at the time I thought it was one of the few times I thought using an indexer would make sense. Haven't used them since =(.

顾挽 2024-09-18 13:04:52

恕我直言,如果您想完善一个打包的 API,那么索引器可能是最好的 - 对于您的普通业务对象来说,这不值得付出努力。

如果您正在制作一些专门的集合,我会将其归类为整理您的打包 API - 即使您将其全部保留在一个模块中。

IMHO, Indexers are probably best if you're trying to spruce up a packaged API - it's not worth the effort for your run of the mill business object.

And if you're making some specialized collection, I'd categorize that as sprucing up your packaged API - even if you keep it all in one module.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文