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

如何通过反射访问派生类型的List属性并调用其重写方法?

问题解决:将List转为可调用BaseClass方法的集合

问题原因

List<T>是不变泛型类型,即便DerivedClass继承自BaseClass,List<DerivedClass>也无法直接转换为List<BaseClass>,因此val as List<BaseClass>会返回null。而IEnumerable<out T>是协变泛型接口(带有out关键字),支持从IEnumerable<DerivedClass>到IEnumerable<BaseClass>的转换。

解决方案

以下是几种可行的实现方式:

方式1:通过IEnumerable<BaseClass>遍历调用

直接将集合转换为支持协变的IEnumerable<BaseClass>,然后遍历执行方法:

var val = prop.GetValue(obj);
if (val is IEnumerable<BaseClass> items)
{
    foreach (var item in items)
    {
        item.DoThing();
    }
}

方式2:使用Cast<BaseClass>转换元素

通过LINQ的Cast方法将集合中的每个元素转换为BaseClass类型:

var val = prop.GetValue(obj);
var items = (val as IEnumerable)?.Cast<BaseClass>();
if (items != null)
{
    foreach (var item in items)
    {
        item.DoThing();
    }
}

方式3:反射遍历集合元素(兼容非泛型场景)

如果需要处理更通用的集合类型(比如非泛型ICollection),可以通过反射获取元素并调用方法:

var val = prop.GetValue(obj);
if (val is IEnumerable collection)
{
    foreach (var item in collection)
    {
        if (item is BaseClass baseObj)
        {
            baseObj.DoThing();
        }
    }
}

完整修正后的代码示例

var pt = prop.PropertyType;

if (pt.IsGeneric && (pt.GetGenericTypeDefinition() == typeof(List<>)) && (pt.GetGenericArguments()[0].IsSubclassOf(typeof(BaseClass))))
{
    var val = prop.GetValue(obj);
    if (val is IEnumerable<BaseClass> items)
    {
        foreach (var item in items)
        {
            item.DoThing();
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 03:40:54