89

我正准备为带有单个参数的事件参数创建一个通用的 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# 提供一个?谢谢你的帮助。

4

7 回答 7

70

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

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

于 2010-07-22T18:34:33.340 回答
34

我必须说我不了解这里所有的“纯粹主义者”。即,如果您已经定义了一个包类——它具有所有细节、属性等——为什么黑客创建一个额外的不必要的类只是为了能够遵循事件/参数机制、签名样式?问题是 - 并非 .NET 中的所有内容 - 或者就此而言“缺失” - 都是“好的” - MS 多年来一直在“纠正”自己......我会说只是去创建一个 - 就像我一样- 因为我就是那样需要它 - 并为我节省了很多时间,

于 2010-10-31T23:08:09.733 回答
10

它确实存在。至少,现在是这样。

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

于 2013-04-09T08:18:32.423 回答
8

如果您选择不使用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
};
于 2014-10-28T01:18:52.760 回答
4

没有内置的通用参数。如果您遵循 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

于 2016-01-13T10:05:25.383 回答
1

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

于 2010-07-22T21:01:49.980 回答
-4

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

除非您只想要一个字符串或类似基本的数据包,在这种情况下,.NET 中可能有 EventArgs 类标准,它们旨在服务于您所达到的任何简单目的。

于 2010-07-22T19:34:40.363 回答