2015-05-27 139 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 *,它将被分配在堆上。 –