我们先来看一个数组:
int[] arr1 = {1, 2, 3};
arr1[1] = 42;
int x = arr1[2];
我们可以通过索引来获取数组中的值;那么我们可以自定义这些索引。
我们先来考虑一下为什么要自定义索引器:
如果我们数组中存的是一个类,而不是简单的整数,字符串,那么我们可能需要多个索引,来获取该类。这时我们仅仅通过整数索引是不够的,那么我们就需要更多的数据类型来获取该类。
下面来举个例子:
先来一个Person类:有姓、名,生日,构造方法,重写ToString方法
public class Person
{
public DateTime Birthday { get; }
public string FirstName { get; }
public string LastName { get; }
public Person(string firstName, string lastName, DateTime birthDay)
{
FirstName = firstName;
LastName = lastName;
Birthday = birthDay;
}
public override string ToString() => $"{FirstName}{LastName}";
}
创建一个Person集合类:里面有私有字段Person数组,构造方法用于存入Perosn数组。
public class PersonCollection
{
private Person[] _people;
public PersonCollection(params Person[] people) =>
_people = people.ToArray();
}
这时候我们就可以存数据了:
var p1 = new Person("Ayrton", "Senna", new DateTime(1960, 3, 21));
var p2 = new Person("Ronnie", "Peterson", new DateTime(1944, 2, 14));
var p3 = new Person("Jochen", "Rindt", new DateTime(1942,4, 18));
var p4 = new Person("Francois", "Cevert", new DateTime(1944, 2, 25));
var coll = new PersonCollection(p1, p2, p3, p4);
这样我们就定义了一个PersonCollection的变量,并将4个Person类存进去。
如果我们取数据的话可以怎么取呢?我们发现这个Person集合类根本不是一个集合或者数组,那么这时我们就需要用到自定义索引器了。该索引器类似于一个属性。来存取Person数据。
public Person this[int index]
{
get => _people[index];
set => _people[index] = value;
}
那么这时我们 就可以取数据了
Console.WriteLine(coll[2]);
通过整数类型的下标来获取_person字段中的数据和存数据。
那么如果我不想通过整数来获取数据,该如何操作呢?可以加一个时间类型的索引器,通过linq和lambda表达式获取数据。但是不能存数据。
public IEnumerable<Person> this[DateTime birthDay]
{
get => _people.Where(p => p.Birthday == birthDay);
}
接下里是调用。
var p1 = new Person("Ayrton", "Senna", new DateTime(1960, 3, 21));
var p2 = new Person("Ronnie", "Peterson", new DateTime(1944, 2, 14));
var p3 = new Person("Jochen", "Rindt", new DateTime(1942,4, 18));
var p4 = new Person("Francois", "Cevert", new DateTime(1944, 2, 25));
var p5 = new Person("zhang", "san", new DateTime(1960, 3, 21));
var coll = new PersonCollection(p1, p2, p3, p4,p5);
Console.WriteLine(coll[2]);
foreach (var r in coll[new DateTime(1960, 3, 21)])
{
Console.WriteLine(r);
}
Console.ReadLine();
输出结果: