我准备为带有单个参数的事件参数创建一个通用的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#是否提供了一个?谢谢你的帮助。
答案 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类,这些类用于满足您的任何简单目的。