2016-08-09 37 views
2

我有一個未知的結構類型數組。當我試圖得到一些指數我得到這個對象的一個​​新實例:Array.GetValue()返回結構對象的新實例

var inst = ((SomeStruct)((Array)arrOfSomeStruct).GetValue(0)); 

現在研究所arrOfSomeStruct不同的實例[0]

什麼是最好的最快的方式來獲得陣列項目的原始實例,而不是使用[]運營商?

+0

什麼是你想這樣做,需要源'struct'? – Enigmativity

+0

你真的想實現什麼?只要__分配一個結構值給一個變量,就像'var inst2 = inst1;'一樣,該值被複制,所以創建一個新的實例。只要__unbox__一個已存在於'object'框中的結構值,就像'var inst =(SomeStruct)obj;'中一樣,創建一個新的值/實例。只要你隱式地__box__一個結構體的值,就像在'public object GetValue(){/ * ... */return someStruct/* boxing! * /; },一個新的實例被創建在一個新的框中。你的結構是可變的還是不可變的,因爲你關心所有這些? –

+0

'var inst = orig_arr.GetValue(0); inst.x = 5; // Now orig_arr.x!= inst.x' – Guy

回答

2

這是默認的行爲與結構。它被複制,未被引用。每個使用struct的交換都是一樣的,而不僅僅是您的GetValue方法(例如this[index])。

作爲Jeppe Stig Nielsen評論:

...值類型的數組,.GetValue(0)返回到一個盒裝參考複製結構值的。另一方面[0]是原始的結構值。如果您分配給變量,則然後複製,如var valueCopy = arr[0];中所示。但是,這主要與可變值類型相關。如果結構有一個可以改變結構值的成員,那麼arr[0].MutateValue();會改變原始結構。當然valueCopy.MutateValue();會改變副本。

你擁有的最佳選擇是使結構成爲一個對象,即。轉到一個班級。

在某些極端案件,使用不安全的代碼是最後一招:

unsafe 
{ 
    Point p = new Point(1, 2); 
    Point*[] points = new Point*[] { &p }; 

    Point* p2 = points[0]; 

    p2->X = 2; // this changes both p and p2 
} 
+2

爲了闡明,對於一個值類型的數組,'.GetValue(0)'返回一個對struct值的_boxed copy_的引用。另一方面,'[0]'是原始的結構值。如果你賦值給一個變量,_then_將被複制,如'var valueCopy = arr [0];'。但是,這主要與可變值類型相關。如果結構體有一個可以改變結構體值的成員,那麼'arr [0] .MutateValue();'會改變原始結構體。當然'valueCopy.MutateValue();'會改變副本。 –

+0

好的,很清楚。感謝澄清。 –

4

如果它是value type,則無法獲得原始文件。如果從方法返回或傳遞給方法,則每個Value Type都將被複制。

要變通,只要你想,你必須使用交互的reference type(class)