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

C#动态对象引用:如何简化Mydata方法的非动态赋值逻辑

嘿,我来帮你解决这个if-else冗余的问题!要实现无分支的动态赋值,有两种实用的思路,我给你详细拆解下:

先明确前提

假设你的Data类属性是按规律命名的(比如variable0、variable1、variable2...),就像你代码片段里暗示的那样,先给出这个类的示例:

public class Data
{
    public string variable0 { get; set; }
    public string variable1 { get; set; }
    public string variable2 { get; set; }
    // 可以根据需求扩展更多variableX属性
}

方案一:反射+属性缓存(动态性最强)

利用属性名的规律性,通过反射动态定位属性并赋值,彻底摆脱if-else。为了避免重复反射的性能损耗,我们可以提前缓存属性信息:

public class YourClassName
{
    public List<Data> _newData = new List<Data>();
    // 提前缓存Data类的属性,避免每次反射查找
    private static readonly Dictionary<int, PropertyInfo> _dataPropertyCache = new Dictionary<int, PropertyInfo>();

    // 静态构造函数初始化缓存
    static YourClassName()
    {
        var dataType = typeof(Data);
        int index = 0;
        while (true)
        {
            var propertyName = $"variable{index}";
            var property = dataType.GetProperty(propertyName);
            if (property == null) break; // 没有更多属性就停止
            _dataPropertyCache.Add(index, property);
            index++;
        }
    }

    public void Mydata(int number, List<string> listData)
    {
        // 先做参数校验,避免索引越界
        if (listData == null) throw new ArgumentNullException(nameof(listData));
        if (number < 1 || number > _dataPropertyCache.Count)
            throw new ArgumentOutOfRangeException(nameof(number), "number超出支持的范围");
        if (listData.Count < number)
            throw new ArgumentException("listData的元素数量不足以匹配number的要求");

        var newDataItem = new Data();
        // 循环赋值,完全替代if-else
        for (int i = 0; i < number; i++)
        {
            if (_dataPropertyCache.TryGetValue(i, out var property) && property.CanWrite)
            {
                property.SetValue(newDataItem, listData[i]);
            }
        }
        _newData.Add(newDataItem);
    }
}

为什么这个方案好用?

  • 完全没有分支判断,不管number是1还是10(只要有对应的variableX属性),代码都能自动适配
  • 静态构造函数只初始化一次缓存,后续调用的性能损耗几乎可以忽略
  • 扩展性极强,新增variableX属性不需要修改Mydata方法,缓存会自动识别

方案二:委托字典映射(性能最优)

如果你的number取值是固定的几个值(比如只能是1、2、3),可以提前把每个number对应的赋值逻辑封装成委托,存在字典里,调用时直接匹配执行:

public class YourClassName
{
    public List<Data> _newData = new List<Data>();
    // 提前定义每个number对应的赋值委托
    private static readonly Dictionary<int, Action<Data, List<string>>> _assignActionMap = new Dictionary<int, Action<Data, List<string>>>
    {
        { 1, (data, list) => data.variable0 = list[0] },
        { 2, (data, list) => { data.variable0 = list[0]; data.variable1 = list[1]; } },
        { 3, (data, list) => { data.variable0 = list[0]; data.variable1 = list[1]; data.variable2 = list[2]; } },
        // 可以继续添加更多number对应的逻辑
    };

    public void Mydata(int number, List<string> listData)
    {
        if (listData == null) throw new ArgumentNullException(nameof(listData));
        if (!_assignActionMap.ContainsKey(number))
            throw new ArgumentOutOfRangeException(nameof(number), "不支持该number值");
        if (listData.Count < number)
            throw new ArgumentException("listData的元素数量不足");

        var newDataItem = new Data();
        // 直接通过字典取委托执行,无任何分支判断
        _assignActionMap[number](newDataItem, listData);
        _newData.Add(newDataItem);
    }
}

这个方案的优势:

  • 性能比反射好,因为委托是直接调用属性赋值,没有反射的开销
  • 代码可读性高,每个number对应的逻辑一目了然
  • 同样摆脱了if-else,符合你要的动态性要求

总结选择建议

  • 如果number的取值范围不固定、Data类的属性会频繁新增,选方案一
  • 如果number是固定的几个值、追求极致性能,选方案二

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:55:48