2010-01-07 39 views
3

我試圖通過反射設置一個值。我創造了這個小測試程序通過反射設置值不起作用

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(); 
    } 

Steping thorugh程序我看到了不正確的命令s.SetValue(headers, 99, null);但是在運行時的setValue的headers.AccountNum值保持爲1。

我錯過了一個明顯的步驟?

+0

可變結構是邪惡的。 http://blogs.msdn.com/ericlippert/archive/2008/05/14/mutating-readonly-structs.aspx –

回答

3

我認爲標題可能會被裝箱到一個新的對象,因爲它是一個結構,然後該對象一收到SetValue就立即收集垃圾。將其更改爲班級並查看問題是否消失。

+0

就是這樣,將它從一個結構體改爲一個類可以解決這個問題。 –

1

SetValue正期待object這會導致headers上的裝箱操作。由於headersstruct,它是一個值類型。因此,製作了一個副本,您正在修改的是盒裝對象,而不是headers

你應該認真考慮避免可變值類型。

Eric Lippert

這是另一個原因,可變的值類型是邪惡的。儘量使價值類型不變。

1

此外,您可以使用結構的unboxed版本。
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(); 
}