.NET是否有内置的EventArgs <t>?</t>

时间:2010-07-22 18:30:46

标签: c# generics eventargs

我准备为带有单个参数的事件参数创建一个通用的EventArgs类:

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

在我这样做之前,C#是否具有内置于该语言的相同功能?我似乎记得在C#2.0发布时遇到类似的东西,但现在我找不到它。

或者换句话说,我是否必须创建自己的通用EventArgs类,或者C#是否提供了一个?谢谢你的帮助。

7 个答案:

答案 0 :(得分:63)

没有。您可能正在考虑EventHandler<T>,它允许您为任何特定类型的EventArgs定义委托。

尽管如此,我个人并不认为EventArgs<T>非常合适。在我看来,在事件args中用作“有效负载”的信息应该是一个自定义类,以使其使用和预期属性非常清晰。使用泛型类将阻止您将有意义的名称放置到位。 (“数据”代表什么?)

答案 1 :(得分:30)

我必须说我不明白这里的所有'纯粹主义者'。 即如果你已经定义了一个包类 - 它具有所有细节,属性等 - 为什么hack创建一个额外的不必要的类只是为了能够遵循事件/ args机制,签名样式? 事情是 - 不是.NET中的所有东西 - 或者说“缺少” - 是“好” - MS多年来一直在“纠正”自己...... 我会说只是去创造一个 - 就像我做的那样 - 因为我需要它就像那样 - 并且节省了我很多时间,

答案 2 :(得分:9)

确实存在。至少,现在确实如此。

您可以在某些不同的Microsoft程序集/命名空间中找到DataEventArgs<TData>,例如Microsoft.Practices.Prism.Events。但是,这些是您可能不会自然地包含在项目中的名称空间,因此您可能只使用自己的实现。

答案 3 :(得分:6)

如果您选择不使用Prism,但仍想尝试通用的 EventArgs 方法。

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

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

//使用以下示例代码声明 ObjAdded 事件

public event EventHandler<GenericEventArgs<TargetObjType>> ObjAdded;

//使用以下示例代码引发 ObjAdded 事件

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

//并且您可以订阅 ObjAdded 事件

SubscriberObj.ObjAdded +=  (object sender, GenericEventArgs<TargetObjType> e) =>
{
    // Here you can explore your e.EventData properties
};

答案 4 :(得分:3)

没有内置ARGS。 如果您遵循Microsoft EventHandler模​​式,那么您实现您建议的派生EventArgs: public class MyStringChangedEventArgs : EventArgs { public string OldValue { get; set; } }

但是 - 如果您的团队风格指南接受简化 - 您的项目可以使用轻量级事件,如下所示:

public event Action<object, string> MyStringChanged;

用法:

// 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);

通常PoC项目使用后一种方法。但是,在专业应用中,请注意FX警察理由#CA1009:https://msdn.microsoft.com/en-us/library/ms182133.aspx

答案 5 :(得分:1)

泛型类型的问题在于,即使DerivedType继承自BaseType,EventArgs(DerivedType)也不会从EventArgs(BaseType)继承。因此,使用EventArgs(BaseType)将阻止以后使用该类型的派生版本。

答案 6 :(得分:-4)

这个不存在的原因是因为最终会发生什么是你实现这个,然后当你去填写T时你应该创建一个具有强类型明确属性的类,它充当你事件的数据包arg,但是在实现过程中,您意识到没有理由不让该类继承EventArgs并将其称为好。

除非您只想要一个字符串或类似于数据包的基本内容,否则在.NET中可能会出现标准的EventArgs类,这些类用于满足您的任何简单目的。