事件和事件订阅的数据大小是多少?

本文关键字:事件 多少 数据 | 更新日期: 2023-09-27 18:06:59

很抱歉没有时间在活动上尝试sizeof但是本着增强google-fu的精神....

  1. 有事件字段的类实例实际内存大小是多少?

  2. 每次订阅一个事件将使用多少实际内存?

我假设每个事件或订阅都有一个指针,但我只是想确定。

考虑这个例子:

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...
    }
}

事件和事件订阅的数据大小是多少?

事件字段只是一个对象引用。
在你将处理程序(委托)放入其中之前,每个类实例只消耗一个指针大小(4或8字节)。

委托实例有四个指针大小的字段,加上标准的CLR对象头。

他们商店

:

  1. 调用封闭委托的目标
  2. 指向的函数的MethodBase
  3. 调用
  4. 的函数指针
  5. 存储实际指向的函数的地址的辅助指针(与打开委托一起使用以重新排列参数)

多播委托(在实践中,所有普通委托)增加两个:

  1. 组播委托指向的委托数组(单个委托为null)
  2. _invocationCount(和IntPtr),用于不同类型的委托

我正在写一篇博客,将更详细地解释这些字段。

事件是一对方法,用于添加和删除订阅(实际上,它是三个方法,但第三个方法通常不用于任何事情)。事件本身不会增加对象实例的大小,但添加/删除逻辑通常必须添加至少一个字段。事件最常见的默认实现是创建一个MultiCastDelegate类型的字段,并使用Delegate。组合可添加订阅和委托。