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

C#使用反射给结构体数组成员赋值报CS0266错误如何解决

问题根因
  • 错误CS0266是因为System.Array是所有数组类型的基类,基类实例赋值给派生类变量时需要显式强转,比如(Address[])arr即可解决该编译报错
  • 反射赋值不生效是因为结构体是值类型,调用FieldInfo.SetValue时传入的结构体参数会被自动装箱为独立的object副本,修改的是副本不会更新原结构体,所以出现赋值后数组还是null的情况
修复方案

本地测试代码修复

将结构体先装箱为同一个object对象操作,修改完成后再拆箱回原变量即可:

struct Person
{
    public Address[] addresses;
}

struct Address
{
    public int nCode;
    public string homeAddress;
}
class Program
{
    static void Main(string[] args)
    {
        Person p = new Person();
        int nSize = 100;
        var fields = typeof(Person).GetFields(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
        // 先将值类型装箱,操作同一个引用对象
        object boxedP = p;
        foreach (var fieldInfo in fields)
        {
            if (fieldInfo.FieldType.IsArray)
            {
                Array arr = Array.CreateInstance(fieldInfo.FieldType.GetElementType(), nSize);
                // 给装箱后的对象赋值
                fieldInfo.SetValue(boxedP, arr);
                // 把修改后的结果写回原结构体
                p = (Person)boxedP;

                if(p.addresses == null)
                {
                    Console.WriteLine("Reflection-Not success");
                }
                else
                {
                    Console.WriteLine("Reflection-success");
                }
            }
        }
    }
}

通用泛型方法实现

你最初的initArray方法可以修改为以下版本,适配所有结构体类型:

using System.Reflection;
using System.IO;

private static void InitArray<T>(ref T item, BinaryReader br) where T : struct
{
    var fields = typeof(T).GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
    // 装箱得到可修改的引用对象
    object boxedItem = item;
    foreach (var arrayFieldInfo in fields)
    {
        if (!arrayFieldInfo.FieldType.IsArray)
        {
            continue;
        }
        // 从流中读取数组长度
        int length = br.ReadInt32();
        // 创建对应类型的数组实例
        Array arr = Array.CreateInstance(arrayFieldInfo.FieldType.GetElementType(), length);
        // 赋值给装箱后的结构体
        arrayFieldInfo.SetValue(boxedItem, arr);
    }
    // 将修改后的结果写回原参数
    item = (T)boxedItem;
}

内容的提问来源于stack exchange,提问作者Thành Long Nguyễn

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.11 11:12:01