I'm wondering why the EventArgs
constructor isn't protected as it seems like waste (although tiny) to allocate resources for an empty object for every event, especially when there is a singleton EventArgs.Empty
that's clearly more efficient t开发者_如何学Pythono use. This surprises me, especially when other parts of the .NET do have a protected/private constructor to avoid multiple, unnecessary allocations, e.g. Comparer<T>
.
Are there any cases where creating a new EventArgs()
(not a subclass) actually makes sense, or is the constructor merely available to ease the usage for non-experienced developers?
I would say that its because the EventArgs
class has the ComVisible
attribute set to true
.
This is supported by the following FxCop rule:
A reference type that is specifically marked as visible to COM contains a public parameterized constructor but does not contain a public default (parameterless) constructor.
A bigger question is "Why always use EventArgs, even if your event does not need any information?". If EventArgs did not have a public constructor you'd not be able to do this.
A good advantage is that if in future you do want to pass information any existing code will still compile. For example the following class started out using just EventArgs, but now passes a string containing some "useful information".
class SomeEventSource
{
public event EventHandler<SomeEventArgs> MyEvent;
public void FireTheEvent()
{
MyEvent(this, new SomeEventArgs("This information is interesting"));
}
}
class SomeEventArgs : EventArgs
{
public SomeEventArgs(string interestingInformation)
{
InterestingInformation = interestingInformation;
}
public string InterestingInformation { get; private set; }
}
This client code was written before the change, but it still compiles. If the original had not used EventArgs then the change would have been more expensive to implement.
class SomeClient
{
private readonly SomeEventSource _source;
public SomeClient()
{
_source = new SomeEventSource();
_source.MyEvent += source_MyEvent;
}
public void RunTest()
{
_source.FireTheEvent();
}
void source_MyEvent(object sender, EventArgs e)
{
// Do something
}
}
There is an annotation on EventArg's constructor which enables it to be optimised in certain situations. EventArgs itself is marked Serializable and ComVisible. Any subclass you create will take advantage of these and fit the pattern.
精彩评论