Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Registering events inside a constructor?

I have been playing around with delegates, events, and anonymous methods. In doing so one point became very clear.

Would it not streamline the process of registering any event methods or delegate functions in the constructor?

My tests shows it works and it prevents you from having to declare them after instantiation (as the constructor of the object does it for you).

In fact, the performance is pretty good. Are there any drawbacks to using the "this" keyword to refer to the current object when constructing / instantiating the object?

This seems to make a lot of sense to me as all the events would be wired up on instantiation.

Are there any areas this might be an issue?

Example:

//Constructor
public SayHello() 
{
  _name = "Unnamed";
  _isUpdated = false;

  // Register event handler via lambda (ananymous method shorthand)
  this.NameChanged += (object sender, EventArgs e) => { Console.WriteLine(e.message)); };
}
like image 827
Qubits Avatar asked Dec 09 '11 12:12

Qubits


2 Answers

There are a couple of potential problems with this approach. First, on the more general side, one should usually favour using method overrides over subscribing to self-published events for performance reasons. Obviously, this isn't possible if the event is exposed by an externally sourced based class that exposes an event without a corresponding overridable method. However, subscribing to self-published events should be an approach of last resort, not a default approach.

The second potential problem is more serious, but it has to do with what the code triggered by the event does, not which object exposes the event. For example, consider the following constructor:

public Foo(Bar bar)
{
    bar.SomeEvent += (s, e) => this.DoSomething();
}

If bar fires SomeEvent on another thread, your Foo instance's DoSomething method could be called before the instance has been fully initialized. This is a fairly well-documented problem in the Java space (see, for example, http://www.ibm.com/developerworks/java/library/j-jtp0618/index.html), but coverage is much sparser for C#/.NET. http://joeduffyblog.com/2010/06/27/on-partiallyconstructed-objects/ provides some detailed coverage for .NET, but it might be more than you wanted to know...

like image 51
Nicole Calinoiu Avatar answered Nov 12 '22 10:11

Nicole Calinoiu


I don't think that there are any issues. It's up to you to do it in that way. You can use the object itself in its constructor. It would work too, if you omitt this.

like image 34
Fischermaen Avatar answered Nov 12 '22 11:11

Fischermaen