事件和事件订阅的数据大小是多少?
抱歉,没有时间在事件上尝试 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...
}
}
Apologies for not quite having the time to try sizeof on an event but in the spirit of enhancing google-fu....
What actual memory size will be added to a class instance which has an event field?
What actual memory will be used for each subscription to an event?
I assume single pointers for each event or subscription, but I just want to be sure.
Consider this example:
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...
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
事件字段只是一个对象引用。
在您将处理程序(委托)放入其中之前,每个类实例只会消耗一个指针大小(4 或 8 字节)。
委托实例有四个指针大小的字段,加上标准的 CLR 对象头。
它们存储:
多播委托(实际上,所有普通委托)再添加两个:
null
)_invocationCount
(一个IntPtr
),针对不同的情况以不同的方式使用 。我正在撰写一篇博客文章,该文章将更详细地解释这些字段
An event field is just an object reference.
Until you put a handler (delegate) in it, it will just consume one pointer-size (4 or 8 bytes) per class instance.
Delegate instance have four pointer-size fields, plus the standard CLR object header.
They store:
Multicast delegates (in practice, all normal delegates) add two more:
null
for single delegates)_invocationCount
(anIntPtr
), used in different ways for different kinds of delegatesI'm in the middle of writing a blog post that will explain these fields in greater detail.
事件是一对方法,用于添加和删除订阅(实际上,它是三个方法,但第三个方法通常不用于任何用途)。事件本身不会向对象实例的大小添加任何内容,但添加/删除逻辑通常必须添加至少一个字段。事件最常见的默认实现是创建一个 MultiCastDelegate 类型的字段,并使用 Delegate.Combine 添加订阅,使用 Delegate.Remove 删除订阅。
An event is a pair of methods, for adding and removing subscriptions (actually, it's a trio of methods, but the third method is generally not used for anything). Events themselves do not add anything to the size of an object instance, but the add/remove logic will usually have to add at least one field. The most common default implementation of an event is to create a field of type MultiCastDelegate, and use Delegate.Combine to add subscriptions and Delegate.Remove to remove them.