2015-05-27 133 views
0

我最近問了一個關於StackOverflowExeptions的問題,這個解釋非常有幫助!
不過,我寫了一個方法,試圖找出其中T cached分配(堆/堆棧):分配在堆或棧上?

private Dictionary<Type, Component> _cachedComponents = new Dictionary<Type, Component>(); 

public T GetCachedComponent<T>() where T : Component { 
    //Not yet sure if the next line works or throws an exception -> just ignore it 
    if(_cachedComponents[typeof(T)] != null) { 
     return (T)_cachedComponents[typeof(T)] 
    } else { 
     T cached = this.GetComponent<T>(); 
     _cachedComponents.Add(typeof(T), cached); 
     return cached; 
    } 
} 
  1. 由於T cached是我認爲它是在棧上分配的方法內聲明,對不對?
  2. 但是,引用然後被添​​加到字典中,這應該被分配在堆上,對吧?
  3. 該方法返回後堆棧被「清除」,對吧?
  4. 但是T cached會發生什麼?
    它會被移動到堆?
    (因爲棧不「攜帶數據」了,但字典仍持有的引用)
+0

Aaaaaaah。不可以。您應該仔細查看有關引用類型和值類型的各種問題。 – xanatos

+2

[該堆棧是一個實現細節](http://blogs.msdn.com/b/ericlippert/archive/2009/04/27/the-stack-is-an-implementation-detail.aspx)試圖想到使用它的程序通常不是正確的心態。 – Servy

+0

[內存分配:堆棧vs堆?]的可能的重複(http://stackoverflow.com/questions/4487289/memory-allocation-stack-vs-heap) –

回答

0

因爲T緩存我以爲這是在棧上分配 方法內聲明,對不對?

T在方法中分配並不影響它在堆或堆棧上。無論是前者還是後者,是基於這是參考類型還是值類型。

但是該引用然後被添​​加到字典中,應該在堆上分配 ,對吧?

一旦參考被加入到Dictionary<TKey, TValue>,密鑰將被存儲在字典中,這是在堆上分配內,因爲它是一個引用類型。

該方法返回後堆棧被「清除」,對吧?

堆棧在方法返回時被清除。

但是,T緩存會發生什麼?它會被移到堆中嗎?

如果T被緩存在字典中,那麼它已經被分配到堆中。總的來說,我假設你問這些問題的一般知識。你不應該擔心這個太多,因爲我在這裏寫的是一個實現細節,並且可能會發生變化。

+0

是的,這是一般性的知識。 :D(你知道它是如何工作的 - 我也想)嗯,但類體內的值類型字段也將被分配在堆上,不是嗎?除此之外,我理解你的輸入:) thx很多 –

+0

如果它是一個*局部變量*,它將被分配在堆棧上。如果它是類聲明中的* field *,它將被分配在堆上。 –