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

C#中如何动态为自定义类的属性赋值?

问题描述

我定义了如下C#类:

public class MyClass
{
    public DateTime Date
    { get; set;}

    public double Col1
    { get; set;}

    public double Col2
    { get; set;}

    public double Col3
    { get; set;}
}

同时我有一个Dictionary<string, double>类型的集合Items,示例数据如Items["AA"] = 23.56、Items["BB"] = 15.456等(键名会动态变化)。

我希望为MyClass的属性动态赋值,尝试了两种思路:
第一种是通过索引方式直接赋值:

MyClass obj = new MyClass();
int i = 0;

foreach (KeyValuePair<string, double> entry in items)
{
    // 为第一个属性(Col1)赋值
    obj[i] = entry.Value;   // 此方式是否可行?
    i++;
}

第二种是通过反射遍历类属性,再从Dictionary中取值赋值:

MyClass obj = new MyClass();
PropertyInfo[] properties = typeof(MyClass).GetProperties();
foreach (PropertyInfo property in properties)
{
    var value = // 从Dictionary中获取对应值
    property.SetValue(obj, value);
}

我的需求是在运行时为MyClass的属性赋值,且无法提前知晓Dictionary中的元素数量,最终要实现类似效果:

MyClass obj = new MyClass();
obj.Col1 = 23.56; // AA对应的值
obj.Col2 = 15.456; // BB对应的值
obj.Col3 = 100.23; // CC对应的值……以此类推

请问该需求是否可行?若可行,具体如何实现?


解决方案

这个需求完全可行,下面针对你的两种思路逐一说明并给出实现方案:

1. 索引方式的可行性

你的第一种思路不可行,因为MyClass并没有实现索引器(this[int index]),直接用obj[i]会编译报错。除非你手动给MyClass添加索引器实现,但这种方式灵活性差,且没必要——反射方案更适合这种动态赋值场景。

2. 反射方案的具体实现

反射是实现这个需求的合理方式,核心思路是:

  • 筛选出MyClass中所有double类型的属性(排除Date属性)
  • 按属性名称排序(保证Col1、Col2、Col3的顺序)
  • 遍历Dictionary的元素,按顺序给对应的属性赋值

完整代码示例

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;

public class MyClass
{
    public DateTime Date { get; set; }
    public double Col1 { get; set; }
    public double Col2 { get; set; }
    public double Col3 { get; set; }
}

public class Program
{
    public static void Main()
    {
        // 示例Dictionary数据
        var items = new Dictionary<string, double>
        {
            {"AA", 23.56},
            {"BB", 15.456},
            {"CC", 100.23}
        };

        MyClass obj = new MyClass();

        // 1. 获取MyClass中所有double类型的属性,排除Date,按名称排序
        var targetProperties = typeof(MyClass)
            .GetProperties(BindingFlags.Public | BindingFlags.Instance)
            .Where(p => p.PropertyType == typeof(double) && p.Name != nameof(MyClass.Date))
            .OrderBy(p => p.Name) // 确保Col1、Col2、Col3的顺序
            .ToList();

        // 2. 遍历Dictionary元素,按顺序给属性赋值
        int propIndex = 0;
        foreach (var entry in items)
        {
            if (propIndex >= targetProperties.Count)
                break; // 超出属性数量时停止赋值

            var property = targetProperties[propIndex];
            property.SetValue(obj, entry.Value);
            propIndex++;
        }

        // 验证结果
        Console.WriteLine($"Col1: {obj.Col1}");
        Console.WriteLine($"Col2: {obj.Col2}");
        Console.WriteLine($"Col3: {obj.Col3}");
    }
}

关键细节说明

  • 属性筛选:通过Where条件排除Date属性,只保留double类型的属性,避免赋值类型不匹配的错误。
  • 顺序保证:Dictionary在C# 3.0及以后版本中会保留插入顺序,但为了稳妥,还是通过OrderBy(p => p.Name)确保Col1、Col2、Col3按顺序匹配Dictionary的元素。如果你的Dictionary需要严格按键排序,可以改用SortedDictionary<string, double>。
  • 边界处理:添加了propIndex >= targetProperties.Count的判断,避免当Dictionary元素数量超过MyClass的double属性数量时引发索引越界异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 21:30:56