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

C#中如何将FieldInfo的值转换为泛型基类列表?

问题原因与解决方案

问题根源

List<SomeDerivedClass> 和 List<SomeSuperClass> 是完全独立的封闭泛型类型,C# 中 List<T> 属于不变类型——即便 SomeDerivedClass 继承自 SomeSuperClass,也无法直接将前者的实例转换为后者。只有支持协变的泛型接口(如 IEnumerable<out T>、IReadOnlyList<out T>)允许这种向上转换,因为这些接口的类型参数被标记为 out(仅用于输出场景)。

解决方法

根据业务需求,有几种可行的处理方式:

1. 转换为协变接口(推荐,无额外内存开销)

利用 List<T> 实现了 IEnumerable<out T> 的特性,先将集合转换为协变接口类型,再按需转为 List<SomeSuperClass>:

public virtual void SomeMethod()
{
    FieldInfo[] fields = GetType().GetFields();

    foreach (FieldInfo fieldInfo in fields)
    {
        if ((fieldInfo.FieldType.IsGenericType) && 
            (fieldInfo.FieldType.GetGenericTypeDefinition() == typeof(List<>)) && 
            (fieldInfo.FieldType.GetGenericArguments()[0].IsSubclassOf(typeof(SomeSuperClass))))
        {
            // 获取派生类列表(断言已确认非空)
            var derivedClassList = fieldInfo.GetValue(this) as List<SomeDerivedClass>;
            Assert.IsNotNull(derivedClassList);

            // 直接转换为基类的IEnumerable(协变支持,无新对象创建)
            IEnumerable<SomeSuperClass> superclassEnumerable = derivedClassList;
            Assert.IsNotNull(superclassEnumerable);

            // 如果需要List<SomeSuperClass>实例,基于Enumerable创建新列表
            List<SomeSuperClass> superclassList = superclassEnumerable.ToList();
            Assert.IsNotNull(superclassList);
        }
    }
}

2. 强制转换元素并生成新列表

如果需要直接得到 List<SomeSuperClass>,可以用 Cast<T> 方法转换集合中的元素:

var derivedList = fieldInfo.GetValue(this) as List<SomeDerivedClass>;
List<SomeSuperClass> superclassList = derivedList.Cast<SomeSuperClass>().ToList();

3. 修改字段声明为协变接口(需权衡可写性)

如果业务允许限制集合的修改操作,可以将 Game 类中的字段声明为协变接口类型,这样就能直接转换为基类的接口实例:

public class Game : SomeSuperClass 
{
    // 用IReadOnlyList<T>声明,支持向上转换为IReadOnlyList<SomeSuperClass>
    public IReadOnlyList<SomeSuperClass> inventory_changes = new List<SomeDerivedClass>();
}

这种方式的缺点是无法通过接口直接添加/删除元素,仅适合只读场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 06:25:20