You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过索引访问和设置C#对象的属性值?

实现HoursOfDay类的索引器访问

需求说明

我有一个模拟一天时段的HoursOfDay类,包含Hour00到Hour23共24个属性,希望不用反射、也不将对象转换为数组/字典,直接像数组或字典那样通过索引访问和设置属性值,支持以下几种访问方式:

var hoursOfDay = new HoursOfDay();
// 三种合法访问方式
var h1 = hoursOfDay[0];          // 数字索引
var h2 = hoursOfDay["0"];        // 单数字字符串
var h3 = hoursOfDay["hour00"];   // 属性名格式字符串

同时支持设置操作:

hoursOfDay[0] = new HourDetailsExample("exampleData");
hoursOfDay["10"] = new HourDetailsExample("morningData");
hoursOfDay["hour23"] = new HourDetailsExample("nightData");

解决方案:实现多类型索引器

在HoursOfDay类中添加int类型索引器和string类型索引器,通过分支判断处理不同的索引输入,直接映射到对应的属性。

完整代码示例

internal class HoursOfDay
{
    [JsonProperty("hour00", NullValueHandling = NullValueHandling.Ignore)]
    public HourDetailsExample Hour00 { get; set; }

    [JsonProperty("hour01", NullValueHandling = NullValueHandling.Ignore)]
    public HourDetailsExample Hour01 { get; set; }

    // ... 省略Hour02到Hour22的属性定义 ...

    [JsonProperty("hour23", NullValueHandling = NullValueHandling.Ignore)]
    public HourDetailsExample Hour23 { get; set; }

    // int类型索引器:直接接收0-23的小时数
    public HourDetailsExample this[int hour]
    {
        get
        {
            return hour switch
            {
                0 => Hour00,
                1 => Hour01,
                2 => Hour02,
                // ... 依次补充3到22的映射 ...
                23 => Hour23,
                _ => throw new ArgumentOutOfRangeException(nameof(hour), "小时数必须在0-23之间")
            };
        }
        set
        {
            switch (hour)
            {
                case 0: Hour00 = value; break;
                case 1: Hour01 = value; break;
                case 2: Hour02 = value; break;
                // ... 依次补充3到22的映射 ...
                case 23: Hour23 = value; break;
                default: throw new ArgumentOutOfRangeException(nameof(hour), "小时数必须在0-23之间");
            }
        }
    }

    // string类型索引器:支持"0"/"00"/"hour00"三种格式
    public HourDetailsExample this[string index]
    {
        get
        {
            // 处理带前缀的情况,比如"hour00"
            if (index.StartsWith("hour", StringComparison.OrdinalIgnoreCase))
            {
                var hourStr = index.Substring(4);
                if (int.TryParse(hourStr, out int hour))
                {
                    return this[hour];
                }
            }
            // 处理纯数字字符串,比如"0"或"00"
            else if (int.TryParse(index, out int hour))
            {
                return this[hour];
            }
            throw new ArgumentException("索引格式不合法,支持格式:0-23数字、\"0\"/\"00\"字符串、\"hour00\"格式字符串", nameof(index));
        }
        set
        {
            // 复用get的逻辑转换为int索引,再调用int索引器的set
            if (index.StartsWith("hour", StringComparison.OrdinalIgnoreCase))
            {
                var hourStr = index.Substring(4);
                if (int.TryParse(hourStr, out int hour))
                {
                    this[hour] = value;
                    return;
                }
            }
            else if (int.TryParse(index, out int hour))
            {
                this[hour] = value;
                return;
            }
            throw new ArgumentException("索引格式不合法,支持格式:0-23数字、\"0\"/\"00\"字符串、\"hour00\"格式字符串", nameof(index));
        }
    }
}

// 假设HourDetailsExample类定义如下
public class HourDetailsExample
{
    public string Data { get; set; }
    public HourDetailsExample(string data)
    {
        Data = data;
    }
}

代码说明

  1. int类型索引器:直接接收0-23的整数,通过switch表达式(get)和switch语句(set)映射到对应的HourXX属性,超出范围抛出异常。
  2. string类型索引器:
    • 自动识别三种输入格式:带"hour"前缀的字符串、纯数字字符串(单/两位)
    • 将合法的字符串索引转换为int索引,复用int索引器的逻辑,减少代码重复
    • 非法格式直接抛出明确的参数异常
  3. 全程未使用反射,也没有将属性转换为数组/字典,完全直接操作类的属性,性能和类型安全性都有保障。

内容的提问来源于stack exchange,提问作者jtmaps

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 10:25:15