通过反射设置值不起作用

时间:2010-01-07 19:46:29

标签: c# reflection struct

我试图通过反思设置一个值。我创建了这个小测试程序

    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。

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

3 个答案:

答案 0 :(得分:3)

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

答案 1 :(得分:1)

SetValue期待object导致headers上的装箱操作。由于headersstruct,因此它是值类型。因此,会制作副本,您要修改的内容是盒装对象,而不是headers

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

来自Eric Lippert

  

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

答案 2 :(得分:1)

您也可以使用未装箱的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(); 
}