2011-07-07 35 views
8
class PriceClass { 

     private int value; 
     public int Value 
     { 
      get { return this.value; } 
      set { this.value = value; } 
     }   
    } 


    struct PriceStruct 
    { 

     private int value; 
     public int Value 
     { 
      get { return this.value; } 
      set { this.value = value; } 
     } 
    } 
    static void Main(string[] args) 
    { 
     PriceClass _priceClass = new PriceClass(); 
     Type type = typeof(PriceClass); 
     PropertyInfo info = type.GetProperty("Value"); 
     info.SetValue(_priceClass, 32, null); 
     Console.WriteLine(_priceClass.Value); 

     PriceStruct _priceStruct = new PriceStruct(); 
     type = typeof(PriceStruct); 
     info = type.GetProperty("Value"); 
     info.SetValue(_priceStruct, 32, null); 
     Console.WriteLine(_priceStruct.Value); 

     Debugger.Break(); 
    } 

印刷的第一個值是32,而第二個是0否拋出異常爲什麼沒有在Struct中設置屬性?

+1

看到接受的回答這個問題:http://stackoverflow.com/questions/6280506/is-there-a-way-to-set-properties-on-struct-instances -using-reflection – Henrik

回答

12

這是因爲裝箱你的結構使它的副本,所以你應該更早地打開它,所以你從你修改相同的數據調用getter。下面的代碼工作:

object _priceStruct = new PriceStruct(); //Box first 
    type = typeof(PriceStruct); 
    info = type.GetProperty("Value"); 
    info.SetValue(_priceStruct, 32, null); 
    Console.WriteLine(((PriceStruct)_priceStruct).Value); //now unbox and get value 

    Debugger.Break(); 
+1

謝謝。 這是我第一次看到強制裝箱(將結構轉換爲對象)並拆箱(將對象轉換回結構)以查看正在發生的事情並理解過程。這很簡單,真的。但是我看到的其他地方,拳擊步驟都是由隱藏進程完成的(由編譯器自動完成),並且沒有意義如何使用它。 –

1

仍然可以使用反射改變它們卻是有點長纏繞。

見下面的例子:http://social.msdn.microsoft.com/Forums/en/netfxbcl/thread/2dd4315c-0d0d-405c-8d52-b4b176997472

+2

+1你的例子顯示我認爲可以做的最好的。在「安全」代碼中使用反射來改變真值類型的字段是不可能的,但是對於每個值類型都有相應的裝箱類類型。轉換爲具有諷刺意味的名稱ValueType會將值類型轉換爲其對應的盒裝類類型的實例,然後可能會使用反射進行變異;突變後,盒裝實例的內容可以被複制回真正的值類型對象。 – supercat

4

結構是值類型,這是由值來傳遞,這意味着你僅繞過整個struct的副本,而不是原來的對象的引用。

因此,當您將其傳遞到info.SetValue(_priceStruct, 32, null)時,副本被傳遞給該方法併發生變異,因此原始對象根本不會被更改。爲什麼可變結構是邪惡的另一個原因。

相關問題