Dan
Dan

Reputation: 3

What are the data sizes for events and event subscription?

Apologies for not quite having the time to try sizeof on an event but in the spirit of enhancing google-fu....

  1. What actual memory size will be added to a class instance which has an event field?

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

Upvotes: 0

Views: 426

Answers (2)

supercat
supercat

Reputation: 81189

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.

Upvotes: 0

SLaks
SLaks

Reputation: 887479

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:

  1. The target to invoke a closed delegate
  2. The MethodBase of the function pointed to
  3. A function pointer to invoke
  4. An auxiliary pointer storing the address of the actual function pointed to (used with open delegates to rearrange parameters)

Multicast delegates (in practice, all normal delegates) add two more:

  1. An array of delegates pointed to by the multicast delegate (null for single delegates)
  2. _invocationCount (an IntPtr), used in different ways for different kinds of delegates

I'm in the middle of writing a blog post that will explain these fields in greater detail.

Upvotes: 3

Related Questions