2011-07-31 78 views
2

在另一個topic中,一位好人告訴我,引用Eric Lippert的話:靜態的意義與編譯器在某個類/結構/字段的編譯時所具有的知識和確定性有關。它與內存位置無關,並且它們被固定或不是等等。反正靜態成員是可移動的還是固定的?

但是我仍然不太確定,因爲編譯器允許下面顯示的內容發生。

 struct MyStruct 
     { 
      public static int[] Arr = {1,3,5}; 
     } 
     static void Test<T>(ref T t) where T:struct 
     { 
      Console.WriteLine (t); 
     } 
     void Main() 
     { 
      Test(ref MyStruct.Arr[2]);//output: as expected 5 
     } 

是裁判的論點完全不同的東西比較C++的引用,或現場銷背後都會發生一些ARG遊戲由參時間的流逝?如果靜態成員是可移動的,運行時如何保證數組元素的地址在執行被調用函數期間不會改變?我從一個實驗中瞭解到,對象'Item prop以外的數組'的返回值不允許被Ref傳遞。我認爲這是因爲數組元素分配在一個連續的內存塊中,但是如果整個數組是可移動的,那麼如何獲取其元素的地址?

我有點被這種不確定性所困擾。如果有人能給出某些答案,我會非常感激。提前致謝!

~~~~~~~~~~~~~~~~~~

理解它:

因此,任何管理操作,只要編譯器允許它發生,我們不應該出汗吧?我有一些C/C++背景,我認爲我理解C++的「靜態」的含義非常好,只有託管代碼的可移動性讓我可疑。任何管理對象,無論它是堆棧還是託管堆,ref參數都可以正確指向它,對吧?

+0

你會感到困惑,因爲靜態在應用於成員函數時意味着不同的東西,而不是應用於對象記憶成員。 [引用Lippert先生的話](http://blogs.msdn.com/b/ericlippert/archive/2007/06/14/calling-static-methods-on-type-parameters-is-illegal-part-one .aspx)僅用於方法。 –

+0

無論如何,如果一個對象被重新定位,所有對該對象的引用(以及其中包含的對象)也將被更新。這就是爲什麼他們是參考,而不是地址。 –

回答

4

C#ref參數並不完全不同於C++引用,但它們在這方面有所不同。

垃圾收集器已知C#ref參數,如果它將對象提升爲不同的代,它將調整它們。

C++引用對.NET垃圾回收器是不可見的,如果目標未被固定並且垃圾回收器運行,它們將會中斷。

(C++/CLI支持.NET的引用和本機參考文獻)

如果靜態構件是可移動的,如何運行時保證陣列元素的地址的執行期間不會改變所謂的功能?

它沒有。但函數將使用更新的地址,因爲它也是.NET代碼。

這些都不會改變,這取決於是否存在引用該數組的靜態字段。 (事實上​​,數組本身並不是靜態的,只是指向它的字段,這個事實使得整個問題變得毫無意義)。

+0

只要被引用的對象被移動,它們會被調整嗎?我是否正確?謝謝! – Need4Steed

+0

@ Need4Steed:沒錯。 –

相關問題