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

C#如何对FieldInfo.GetValue返回的对象进行动态类型转换

解决方案

你期望的运行时动态类型强转语法C#不支持,强转目标类型必须在编译期确定,可通过以下三种方案实现同等效果:

方案1:定义公共接口/抽象基类(最推荐,编译期类型安全)

所有BoolEventProperty/FloatEventProperty/IntEventProperty均包含Value成员,你可以先定义公共非泛型接口,让所有属性类实现该接口:

// 定义公共接口
public interface IEventProperty
{
    object Value { get; }
}

// 各个属性类实现接口示例
public class BoolEventProperty : IEventProperty
{
    public bool Value { get; set; }
    object IEventProperty.Value => Value;
}
// FloatEventProperty、IntEventProperty同理实现IEventProperty接口即可

遍历逻辑可直接简化为:

foreach (var v in typeof(CentralParams).GetFields())
{
    var fieldValue = v.GetValue(_centralParams);
    if (fieldValue is IEventProperty prop)
    {
        print($"{v.Name}   {prop.Value}");
    }
}

该方案编译期即可完成类型校验,不会出现运行时成员不存在的问题,后续新增属性类型只要实现IEventProperty即可自动适配,无需修改遍历逻辑。

方案2:使用dynamic关键字(实现最简单,适合确定所有字段都有Value成员的场景)

C#的dynamic类型会在运行时解析成员,不需要编译期确定类型,直接改写遍历逻辑即可:

foreach (var v in typeof(CentralParams).GetFields())
{
    dynamic prop = v.GetValue(_centralParams);
    try
    {
        print($"{v.Name}   {prop.Value}");
    }
    catch (RuntimeBinderException)
    {
        // 可在此处处理字段无Value成员的异常情况
    }
}

注意:如果字段值不存在Value成员,会抛出运行时异常,建议加异常捕获做兼容。

方案3:反射读取Value属性(无侵入,不需要修改原有属性类定义)

如果不能修改XXXEventProperty的定义,也不想用dynamic,可以直接通过反射读取Value属性:

foreach (var v in typeof(CentralParams).GetFields())
{
    var fieldValue = v.GetValue(_centralParams);
    var valueProp = fieldValue.GetType().GetProperty("Value");
    if (valueProp != null)
    {
        var value = valueProp.GetValue(fieldValue);
        print($"{v.Name}   {value}");
    }
}

该方案不需要修改原有类的代码,适配性最强,性能略低于前两种方案,常规遍历场景下感知不到差异。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 17:36:03