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

C#反射遍历枚举类型列表:无需硬编码获取元素的方法

问题

尝试从类中自动生成带默认值的UI,但无法获取枚举类型列表中的元素。已编写测试示例,希望在不硬编码所有枚举列表类型组合、不添加switch case语句的前提下,访问列表中的数据。

测试代码:

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

public class Program
{
    public static void Main()
    {
        var options = new Options();
        
        options.Foods = new List<Food>() {Food.Chips, Food.Pie};
        options.Drinks = new List<Drink>() {Drink.Lemonade,Drink.Water};
        
        foreach (PropertyInfo propertyInfo in options.GetType().GetProperties())
        {
            Console.WriteLine(propertyInfo.Name);
            object vals = propertyInfo.GetValue(options);
            var type = propertyInfo.PropertyType.GetGenericArguments()[0];
            
            Console.WriteLine(type);
            

// Error is here, how can I loop through a enum list without 
// hard coding in each List<enum> type. 

            foreach(var item in vals as IEnumerable<object>)
            {
                Console.WriteLine("--" + item.ToString());
            }
        }

    }
    
}


public class Options
{
    public List<Food> Foods {get;set;}
    public List<Drink> Drinks {get;set;}
}


public enum Food
{
    Chips,
    Fish,
    Burger,
    Pie,
    Mash
    
}

public enum Drink
{
    Cola,
    Lemonade,
    Water
}
解决方案

问题根源是List<枚举类型>属于值类型泛型集合,无法直接转换为IEnumerable<object>(值类型的泛型集合不会自动装箱为object枚举)。以下两种方案可实现通用处理:

方法1:使用非泛型IEnumerable接口

直接将列表转换为非泛型的IEnumerable,遍历过程中元素会自动装箱为object:

foreach (PropertyInfo propertyInfo in options.GetType().GetProperties())
{
    Console.WriteLine(propertyInfo.Name);
    object vals = propertyInfo.GetValue(options);
    var type = propertyInfo.PropertyType.GetGenericArguments()[0];
    
    Console.WriteLine(type);

    // 改用非泛型IEnumerable遍历
    if (vals is IEnumerable enumerable)
    {
        foreach (var item in enumerable)
        {
            Console.WriteLine("--" + item.ToString());
        }
    }
}

方法2:反射调用泛型方法

如果需要对枚举值执行更多定制操作,可定义泛型方法并通过反射调用:

public static void Main()
{
    var options = new Options();
    
    options.Foods = new List<Food>() {Food.Chips, Food.Pie};
    options.Drinks = new List<Drink>() {Drink.Lemonade,Drink.Water};
    
    foreach (PropertyInfo propertyInfo in options.GetType().GetProperties())
    {
        Console.WriteLine(propertyInfo.Name);
        object vals = propertyInfo.GetValue(options);
        var elementType = propertyInfo.PropertyType.GetGenericArguments()[0];
        
        Console.WriteLine(elementType);

        // 反射调用泛型方法处理列表
        typeof(Program).GetMethod("ProcessEnumList", BindingFlags.NonPublic | BindingFlags.Static)
                       .MakeGenericMethod(elementType)
                       .Invoke(null, new[] { vals });
    }
}

private static void ProcessEnumList<T>(List<T> list) where T : Enum
{
    foreach (var item in list)
    {
        Console.WriteLine("--" + item.ToString());
        // 可在此添加枚举专属操作,比如获取枚举描述、数值等
    }
}

两种方案均无需硬编码具体枚举类型或添加switch case,完全通过反射与泛型实现通用化处理。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 11:50:23