通过索引获取对象的属性值



问题:

我有一个对象,其属性为一天中的时间建模。我想知道是否可以像在数组或字典中索引一样对这个对象的属性进行索引,然后通过它们的索引获取这些值。

示例:

internal class HoursOfDay
{
[JsonProperty("hour00", NullValueHandling = NullValueHandling.Ignore)]
public HourDetailsExample Hour00 { get; set; }
[JsonProperty("hour01", NullValueHandling = NullValueHandling.Ignore)]
public HourDetailsExample Hour01 { get; set; }
[JsonProperty("hour02", NullValueHandling = NullValueHandling.Ignore)]
public HourDetailsExample Hour02 { get; set; }
[JsonProperty("hour03", NullValueHandling = NullValueHandling.Ignore)]
public HourDetailsExample Hour03 { get; set; }
[JsonProperty("hour04", NullValueHandling = NullValueHandling.Ignore)]
public HourDetailsExample Hour04 { get; set; }
[JsonProperty("hour05", NullValueHandling = NullValueHandling.Ignore)]
public HourDetailsExample Hour05 { get; set; }
[JsonProperty("hour06", NullValueHandling = NullValueHandling.Ignore)]
public HourDetailsExample Hour06 { get; set; }
[JsonProperty("hour07", NullValueHandling = NullValueHandling.Ignore)]
public HourDetailsExample Hour07 { get; set; }
[JsonProperty("hour08", NullValueHandling = NullValueHandling.Ignore)]
public HourDetailsExample Hour08 { get; set; }
...

如果可能的话,我希望能够访问这个对象的属性,如下所示:

var hoursOfDay = new HoursOfDay(); 
var h1 = hoursOfDay["0"] // or hoursOfDay[0] or hoursOfDay["hour00"]

我知道我可以把这个对象变成一个数组或字典,但我只是好奇是否可以对对象的属性进行索引。

编辑我也明白这是我可以通过反思来做的事情。我想知道我是否可以做索引。

Edit2同样,我也想知道如何更新setter:例如:var h1[0] = new HourDetailsExample("exampleData");

**Edit3**我已经了解到,可以通过调整以下答案来添加这样的设置器:

set
{
switch (index)
{
case 0:
Hour00 = value; break;
case 1:
Hour01 = value; break;
...
default: break;
}
}

您可以在类中创建索引器

public HourDetailsExample this[int index] => index switch {
0 => Hour00,
1 => Hour01,
2 => Hour02,
3 => Hour03,
4 => Hour04,
5 => Hour05,
6 => Hour06,
7 => Hour07,
8 => Hour08,
_ => throw new IndexOutOfRangeException()
};

你可以用字符串索引变量来重载它:

public HourDetailsExample this[string index] => index.ToLowerInvariant() switch {
"0" or "hour00" => Hour00,
"1" or "hour01" => Hour01,
"2" or "hour02" => Hour02,
"3" or "hour03" => Hour03,
"4" or "hour04" => Hour04,
"5" or "hour05" => Hour05,
"6" or "hour06" => Hour06,
"7" or "hour07" => Hour07,
"8" or "hour08" => Hour08,
_ => throw new IndexOutOfRangeException()
};

现在,所有这些变体都是可能的:

var hoursOfDay = new HoursOfDay();
var h1 = hoursOfDay[0];
var h2 = hoursOfDay["1"];
var h3 = hoursOfDay["Hour02"];
var h4 = hoursOfDay["hour03"];

如果您需要通过索引分配值,索引器也可以有一个setter:

public HourDetailsExample this[int index]
{
get => index switch {
0 => Hour00,
...
_ => throw new IndexOutOfRangeException()
};
set {
switch (index) {
case 0: Hour00 = value; break;
case 1: Hour01 = value; break;
case 2: Hour02 = value; break;
case 3: Hour03 = value; break;
case 4: Hour04 = value; break;
case 5: Hour05 = value; break;
case 6: Hour06 = value; break;
case 7: Hour07 = value; break;
case 8: Hour08 = value; break;
default: throw new IndexOutOfRangeException();
}
}
}

您可以始终为以下类型创建索引器:

internal class HoursOfDay
{
// ...

public HourDetailsExample this[int index]
{
get => index switch
{
0 => Hour00,
1 => Hour01,
// ...
_ => throw new ArgumentOutOfRangeException(nameof(index), index, null) // or return null
};
}
}

如果你不想手写所有内容——你可以使用一些反射,但会有一些性能打击(尽管它大多可以通过"缓存"来否定——请参阅这个答案以获得一些灵感)。

最新更新