Does .NET have a built-in EventArgs?

2019-01-07 17:50发布

I am getting ready to create a generic EventArgs class for event args that carry a single argument:

public class EventArg<T> : EventArgs
{
    // Property variable
    private readonly T p_EventData;

    // Constructor
    public EventArg(T data)
    {
        p_EventData = data;
    }

    // Property for EventArgs argument
    public T Data
    {
        get { return p_EventData; }
    }
}

Before I do that, does C# have the same feature built in to the language? I seem to recall coming across something like that when C# 2.0 came out, but now I can't find it.

Or to put it another way, do I have to create my own generic EventArgs class, or does C# provide one? Thanks for your help.

7条回答
看我几分像从前
2楼-- · 2019-01-07 18:10

The reason this does not exist is because what would end up happening is you implement this, and then when you go to fill in the T you should create a class with strongly typed unambiguous properties that acts as the data bag for your event arg, but halfway through implementing that you realize there's no reason you don't just make that class inherit from EventArgs and call it good.

Unless you just want a string or something similarly basic for your data bag, in which case there are probably EventArgs classes standard in .NET which are meant to serve whatever simple purpose you're getting at.

查看更多
你好瞎i
3楼-- · 2019-01-07 18:15

It does exist. At least, it does now.

You can find DataEventArgs<TData> in some different Microsoft assemblies/namespaces, for instance Microsoft.Practices.Prism.Events. However these are namespaces that you might not find natural to include in your project so you might just use your own implementation.

查看更多
小情绪 Triste *
4楼-- · 2019-01-07 18:15

In case you choose not to use Prism, but still would like to try a generic EventArgs approach.

public class GenericEventArgs<T> : EventArgs
{
    public T EventData { get; private set; }

    public GenericEventArgs(T EventData)
    {
        this.EventData = EventData;
    }
}

// Use the following sample code to declare ObjAdded event

public event EventHandler<GenericEventArgs<TargetObjType>> ObjAdded;

// Use the following sample code to raise ObjAdded event

private void OnObjAdded(TargetObjType TargetObj)
{
    if (ObjAdded!= null)
    {
        ObjAdded.Invoke(this, new GenericEventArgs<TargetObjType>(TargetObj));
    }
}

// And finnaly you can subscribe your ObjAdded event

SubscriberObj.ObjAdded +=  (object sender, GenericEventArgs<TargetObjType> e) =>
{
    // Here you can explore your e.EventData properties
};
查看更多
Bombasti
5楼-- · 2019-01-07 18:15

THERE IS NO BUILT-IN GENERIC ARGS. If you follow Microsoft EventHandler pattern, then you implement your derived EventArgs like you suggested: public class MyStringChangedEventArgs : EventArgs { public string OldValue { get; set; } }.

HOWEVER - if your team style guide accepts a simplification - your project can use a lightweight events, like this:

public event Action<object, string> MyStringChanged;

usage :

// How to rise
private void OnMyStringChanged(string e)
{
    Action<object, string> handler = MyStringChanged;    // thread safeness
    if (handler != null)
    {
        handler(this, e);
    }
}

// How to handle
myObject.MyStringChanged += (sender, e) => Console.WriteLine(e);

Usually a PoC projects use the latter approach. In professional applicatons, however, be aware of FX cop justification #CA1009: https://msdn.microsoft.com/en-us/library/ms182133.aspx

查看更多
甜甜的少女心
6楼-- · 2019-01-07 18:22

I must say I don't understand all the 'purists' here. i.e. if you already have a bag class defined - which has all the specifics, properties etc. - why the hack create one extra unnecessary class just to be able to follow the event/args mechanism, signature style? thing is - not everything that is in .NET - or is 'missing from' for that matter - is 'good' - MS's been 'correcting' itself for years... I'd say just go and create one - like I did - cause I needed it just like that - and saved me lot of time,

查看更多
你好瞎i
7楼-- · 2019-01-07 18:27

The problem with a generic type is that even if DerivedType inherits from BaseType, EventArgs(DerivedType) would not inherit from EventArgs(BaseType). Using EventArgs(BaseType) would thus prevent later using a derived version of the type.

查看更多
登录 后发表回答