抱歉没有时间尝试sizeof参加活动,但本着加强google-fu的精神....
将为具有事件字段的类实例添加什么实际内存大小?
每次订阅活动会使用什么实际内存?
我假设每个事件或订阅的单个指针,但我只是想确定。
考虑这个例子:
public class VertexMovedArgs : EventArgs {
public Vertex theVert;
}
public class Vertex {
// what size does this add to each Vertex?
public event EventHandler<VertexMovedArgs> VertexMovedEvent;
private Vector3 m_pos;
public Vector3 pos {
get { return m_pos; }
set {
if ( value != m_pos ) {
m_pos = value;
EventHandler<VertexMovedArgs> tellEveryoneWeMoved = VertexMovedEvent;
if ( handler != null ) {
VertexMovedArgs args = new VertexMovedArgs( this );
tellEveryoneWeMoved( this, args );
}
}
}
}
}
public class Mesh {
private List<Vertex> m_verts = new List<Vertex>();
public Vertex AddVert() {
Vertex vert = new Vertex();
// what size per-subscription does this add to this Mesh instance (or elsewhere)?
vert.VertexMovedEvent += onVertexMoved;
m_verts.Add( vert );
}
void onVertexMoved( object sender, VertexMovedArgs args ) {
// play the vertex like a violin, etc...
}
}
答案 0 :(得分:2)
事件字段只是一个对象引用 直到你在其中放置一个处理程序(委托),它将只消耗每个类实例一个指针大小(4或8个字节)。
Delegate实例有四个指针大小的字段,加上标准的CLR对象标题。
他们存储:
多播代理(在实践中,所有普通代理)再增加两个:
null
代表单个代表)_invocationCount
(IntPtr
),以不同方式用于不同类型的代表我正在撰写一篇博文,其中将更详细地解释这些领域。
答案 1 :(得分:0)
事件是一对方法,用于添加和删除订阅(实际上,它是三个方法,但第三种方法通常不用于任何方法)。事件本身不会添加任何对象实例的大小,但添加/删除逻辑通常必须添加至少一个字段。事件的最常见默认实现是创建MultiCastDelegate类型的字段,并使用Delegate.Combine添加订阅,使用Delegate.Remove删除它们。