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

如何读取对象关联列表CourseEvents的属性名与属性值?

问题描述

现有以下C#模型类:

public class Course
{
    public Guid Id { get; set; }
    public string Title { get; set; }
    public IList<CourseEvent> CourseEvents { get; set; }
}

public class CourseEvent
{
    public Guid Id { get; set; }
    public Guid CourseId { get; set; }
    public DateTime StartDate { get; set; }
}

以及一个读取对象属性名与值的方法:

private void WritePropertyNames(object obj)
{
    foreach (var item in obj.GetType().GetProperties())
    {
        Console.WriteLine(item.Name + " => " + item.GetValue(obj, null));
    }
}

调用示例:

var course = new Course { Title = "My course", CourseEvents = new List<CourseEvent>() { new() { StartDate = DateTime.Today }, new() { StartDate = DateTime.Today.AddDays(-1) } } };

WritePropertyNames(course);

但该方法无法获取关联列表CourseEvents中元素的属性名与值。我尝试了以下错误代码,请问正确实现方式是什么?

foreach (var item2 in obj.GetType().GetProperty("CourseEvents").GetType().GetProperties())
{
    Console.WriteLine(item2.Name + " => " + item2.GetValue(obj, null));
}
正确实现方式

错误原因分析

你写的错误代码存在两个核心问题:

  1. obj.GetType().GetProperty("CourseEvents").GetType() 获取的是PropertyInfo的类型,而非列表元素CourseEvent的类型,遍历的是属性信息类的属性,不是目标元素的属性。
  2. 未获取到列表的实际实例,也没有遍历列表中的单个元素。

递归遍历实现

要解决这个问题,需要通过递归遍历处理嵌套结构:如果对象属性是集合/列表类型,就逐个取出元素再遍历其属性;如果是普通对象则直接遍历属性。修改后的方法如下:

private void WritePropertyNames(object obj, int indentLevel = 0)
{
    if (obj == null)
        return;

    // 生成缩进,让嵌套结构的输出更清晰
    string indent = new string(' ', indentLevel * 4);
    Type objType = obj.GetType();

    // 处理集合类型(排除字符串,因为字符串也实现IEnumerable但无需遍历字符)
    if (obj is IEnumerable enumerable && !(obj is string))
    {
        int index = 0;
        foreach (var element in enumerable)
        {
            Console.WriteLine($"{indent}[{index}] ----------------");
            WritePropertyNames(element, indentLevel + 1);
            index++;
        }
        return;
    }

    // 遍历普通对象的属性
    foreach (var prop in objType.GetProperties())
    {
        object value = prop.GetValue(obj, null);
        Console.WriteLine($"{indent}{prop.Name} => {value}");
        
        // 递归处理复杂对象/集合(排除值类型和字符串)
        if (value != null && !(value is string) && !value.GetType().IsValueType)
        {
            WritePropertyNames(value, indentLevel + 1);
        }
    }
}

调用示例

使用原course对象调用修改后的方法:

var course = new Course 
{ 
    Title = "My course", 
    CourseEvents = new List<CourseEvent>() 
    { 
        new() { StartDate = DateTime.Today }, 
        new() { StartDate = DateTime.Today.AddDays(-1) } 
    } 
};

WritePropertyNames(course);

输出示例

Id => 00000000-0000-0000-0000-000000000000
Title => My course
CourseEvents => System.Collections.Generic.List`1[CourseEvent]
    [0] ----------------
        Id => 00000000-0000-0000-0000-000000000000
        CourseId => 00000000-0000-0000-0000-000000000000
        StartDate => 2024/5/20 00:00:00
    [1] ----------------
        Id => 00000000-0000-0000-0000-000000000000
        CourseId => 00000000-0000-0000-0000-000000000000
        StartDate => 2024/5/19 00:00:00

关键说明

  • 增加indentLevel参数控制输出缩进,让嵌套层级更直观。
  • 排除字符串类型的集合判断,避免无意义的字符遍历。
  • 递归处理所有复杂对象和集合,确保所有层级的属性都被遍历到。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 15:00:49