【问题标题】:Setting a value through reflection is not working通过反射设置值不起作用
【发布时间】:2026-02-15 11:00:01
【问题描述】:

我正在尝试通过反射设置一个值。我创建了这个小测试程序

    struct headerIndexes
    {
        public int AccountNum{ get; set; }
        public int other { get; set; }
        public int items { get; set; }
    }
    static void Main(string[] args)
    {

        headerIndexes headers = new headerIndexes();
        headers.AccountNum = 1;
        Console.WriteLine("Old val: {0}", headers.AccountNum);
        foreach (var s in headers.GetType().GetProperties())
        {
            if (s.Name == "AccountNum")
                s.SetValue(headers, 99, null);
        }
        Console.WriteLine("New val: {0}", headers.AccountNum);
        Console.ReadKey();
    }

通过程序,我看到它正确地执行了命令s.SetValue(headers, 99, null);,但是当 setValue 运行时 headers.AccountNum 的值保持为 1。

我错过了一个明显的步骤吗?

【问题讨论】:

标签: c# reflection struct


【解决方案1】:

我认为标头可能会被装箱到一个新对象中,因为它是一个结构,然后一旦 SetValue 返回,该对象就会被垃圾收集。将其更改为一个类,看看问题是否消失。

【讨论】:

  • 就是这样,将其从结构更改为类解决了问题。
【解决方案2】:

SetValue 期待 object,这会导致对 headers 的装箱操作。因为headersstruct,所以它是一个值类型。因此制作了一个副本,您正在修改的是装箱对象,而不是 headers

您应该认真考虑避免使用可变值类型。

来自Eric Lippert

这也是可变值类型邪恶的另一个原因。尝试始终使值类型不可变。

【讨论】:

    【解决方案3】:

    您也可以使用未装箱版本的 struct。
    object unboxedHeader=headers;
    s.SetValue(unboxedHeader, 99, null);

    struct headerIndexes 
    { 
        public int AccountNum{ get; set; } 
        public int other { get; set; } 
        public int items { get; set; } 
    } 
    static void Main(string[] args) 
    { 
    
        headerIndexes headers = new headerIndexes(); 
        headers.AccountNum = 1; 
        Console.WriteLine("Old val: {0}", headers.AccountNum); 
        object unboxedHeader=headers;
        foreach (var s in headers.GetType().GetProperties()) 
        { 
            if (s.Name == "AccountNum") 
                s.SetValue(unboxedHeader, 99, null); 
        } 
        Console.WriteLine("New val: {0}", headers.AccountNum); 
        Console.ReadKey(); 
    } 
    

    【讨论】:

      最近更新 更多