每次我深入开始一个C#项目时,我最终都会遇到许多事件,这些事件实际上只需要传递一个项目.我坚持EventHandler/ EventArgs练习,但我喜欢做的事情是这样的:
public delegate void EventHandler<T>(object src, EventArgs<T> args);
public class EventArgs<T>: EventArgs {
private T item;
public EventArgs(T item) {
this.item = item;
}
public T Item {
get { return item; }
}
}
Run Code Online (Sandbox Code Playgroud)
后来,我可以拥有我的
public event EventHandler<Foo> FooChanged;
public event EventHandler<Bar> BarChanged;
Run Code Online (Sandbox Code Playgroud)
但是,似乎.NET的标准是EventArgs为每种类型的事件创建一个新的委托和子类.我的通用方法有问题吗?
EventHandler<TEventArgs>,所以你不需要创建泛型委托,但是你仍然需要泛型EventArgs<T>类,因为TEventArgs: EventArgs.
public event EventHandler<EventArgs<Foo>> FooChanged;
Run Code Online (Sandbox Code Playgroud)
与
public event EventHandler<Foo> FooChanged;
Run Code Online (Sandbox Code Playgroud)
但是客户注册你的事件可能会很麻烦,因为系统命名空间是默认导入的,因此他们必须手动寻找你的命名空间,即使使用像Resharper这样的花哨工具......任何人都有任何与此有关的想法?
第二个参数是从EventArgs派生的类型,它提供保存事件数据所需的任何字段或属性.
并且似乎通常建议在.Net文档中使用.
然而事实证明我可以做以下工作正常:
public event EventHandler<int> Panned;
Run Code Online (Sandbox Code Playgroud)
并调用事件处理程序:
int value = 10;
if (Panned != null)
{
Panned(this, value);
}
Run Code Online (Sandbox Code Playgroud)
在观察者方面:
subject.Panned += (sender, e) =>
{
Console.WriteLine(e);
};
Run Code Online (Sandbox Code Playgroud)
对我来说,这似乎不是乱抛垃圾与继承的小类的代码更好的EventArgs或一般EventArgs的建议确实.NET有一个内置的EventArgs <T>?
那么为什么我需要EventHandler从中继承泛型参数EventArgs呢?
我有许多EventArgs类,只有一个字段和一个适当的属性来读取它:
public class SomeEventArgs : EventArgs
{
private readonly Foo f;
public SomeEventArgs(Foo f)
{
this.f = f;
}
public Foo Foo
{
get { return this.f; }
}
}
Run Code Online (Sandbox Code Playgroud)
是否有任何内置的泛型类来实现这样的行为,或者我必须自己滚动?
public class GenericEventArgs<T> : EventArgs
{
private readonly T value;
public GenericEventArgs(T v)
{
this.value = v;
}
public T Value
{
get { return this.value; }
}
}
Run Code Online (Sandbox Code Playgroud)
PS我在Microsoft Connect上写了一个建议
Are EventArg类的海报现在需要我们有泛型并且.NET是否有内置的EventArgs <T>?建议不要使用通用的EventArgs,至少这是我得到的感觉.
当我需要的只是其中一种内置类型时,使用它是否合理?在我的特定情况下,我正在通过TCP读取流,并且当收到数据时,将通知订阅者.
public event EventHandler<EventArgs<string>> data_received = delegate { };
...
while (!reader.EndOfStream)
{
if ((data = reader.ReadLine()) != "")
{
this.data_received(this, new EventArgs<string>(data));
}
}
Run Code Online (Sandbox Code Playgroud)
或者,事件可能不是向订阅者传递数据的最佳方式?
在下面的代码中,我需要知道在引发事件时传递两个字符串的语法.
[PublishEvent("Click")]
public event EventHandler<EventArgs<string>> MyEvent;
Run Code Online (Sandbox Code Playgroud)
谢谢,撒克逊人.
我正在处理的项目要求我能够在每次将项目添加到列表时触发事件.为此,我创建了一个继承自List的自定义List类,并添加了一个OnAdd事件.我还想返回作为EventArgs添加的项目,我为其添加了一些代码(如下所示):
public class ClientListObservable<Client>:List<Client>
{
public event EventHandler<EventArgs<Client>> OnAdd;
public void Add(Client item)
{
if (null != OnAdd)
{
OnAdd(this, new EventArgs<Client>(item));
}
base.Add(item);
}
}
public class EventArgs<Client> : EventArgs
{
public EventArgs(Client value)
{
m_value = value;
}
private Client m_value;
public Client Value
{
get { return m_value; }
}
}
Run Code Online (Sandbox Code Playgroud)
这是我添加处理程序的方式
clientList.OnAdd += new EventHandler<EventArgs<Client>>(clientList_OnAdd);
Run Code Online (Sandbox Code Playgroud)
但是,在OnAdd方法中:
private void clientList_OnAdd(object sender, EventArgs e)
{
//want to be able to access the data members of the Client object …Run Code Online (Sandbox Code Playgroud) 在.NET框架中是否已经提供了类似的东西?
public class EventArgs<T> : EventArgs {
private readonly T data;
public EventArgs(T data) {
this.data = data;
}
}
Run Code Online (Sandbox Code Playgroud)
我知道有一个通用的事件处理程序,我有点惊讶我找不到一个通用的EventArgs类.
谢谢
使用泛型DataEventArgs<TData>类,而不是在事件声明中声明和使用自定义EventArgs继承类,违反.Net事件"模式"约定?或者在某些情况下考虑不好的做法?
(命名事件args 的命名约定是使用事件名称并附加后缀"EventArgs".使用DataEventArgs<TData>省略事件名称,尽管它显示了传输的数据类型.)
您可能会争辩说,通用DataEventArgs类对扩展是封闭的,例如添加另一个属性,除非您可以修改用于TData的类.
更长的解释:
在声明包含一些数据的标准委托事件时,我理解标准事件"模式"约定是使用通用的EventHandler委托声明它:
public event EventHandler<SomethingHappendEventArgs> SomethingHappend;
Run Code Online (Sandbox Code Playgroud)
具体SomethingHappendEventArgs是什么声明的东西
public class SomethingHappendEventArgs : EventArgs
{
public SomeDataType Value { get; private set; }
public SomethingHappendEventArgs(SomeDataType data)
{
this.Value = data;
}
}
Run Code Online (Sandbox Code Playgroud)
当谷歌搜索时,我注意到有几个Microsoft命名空间提供了一个通用的DataEventArgs类,(包括Microsoft.Practices.Prism.Events).但是,我无法找到任何推荐或约定指示何时使用它而不是自定义事件数据类,如SomethingHappendEventArgs,反之亦然.
所以,只要有一个数据块,我要在事件数据包括,是否有我应使用自定义的事件数据类,像SomethingHappendEventArgs,而不是宣布这样的事件的任何原因?
public event EventHandler<DataEventArgs<SomeDataType>> SomethingHappend;
Run Code Online (Sandbox Code Playgroud)
泛型DataEventArgs可以声明如下:
public class DataEventArgs<TData> : EventArgs
{
public TData Value { get; private set; }
public DataEventArgs(TData value)
{
this.Value = value;
}
}
Run Code Online (Sandbox Code Playgroud)