Chr*_*org 21 .net c# generics events
每次我深入开始一个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这样的花哨工具......任何人都有任何与此有关的想法?
Ily*_*kov 27
自.NET Framework 2.0以来,已添加以下表单的委托
public delegate void EventHandler<TArgs>(object sender, TArgs args) where TArgs : EventArgs
Run Code Online (Sandbox Code Playgroud)
您的方法更进一步,因为您为具有单个数据项的EventArgs提供了开箱即用的实现,但它缺少原始想法的几个属性:
所以,我认为最好使用通用的EventHandler <T>,但仍然有自定义的EventArgs类,根据数据模型的要求进行组织.使用Visual Studio和ReSharper之类的扩展,创建新类只需要很少的命令.
为了使通用事件声明更容易,我为它创建了几个代码片段.要使用它们:
Visual Studio 2008\Code Snippets\Visual C#\ My Code Snippets
这是一个使用自定义EventArgs类和一个属性的类:
<?xml version="1.0" encoding="utf-8" ?>
<CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
<CodeSnippet Format="1.0.0">
<Header>
<Title>Generic event with one type/argument.</Title>
<Shortcut>ev1Generic</Shortcut>
<Description>Code snippet for event handler and On method</Description>
<Author>Ryan Lundy</Author>
<SnippetTypes>
<SnippetType>Expansion</SnippetType>
</SnippetTypes>
</Header>
<Snippet>
<Declarations>
<Literal>
<ID>type</ID>
<ToolTip>Type of the property in the EventArgs subclass.</ToolTip>
<Default>propertyType</Default>
</Literal>
<Literal>
<ID>argName</ID>
<ToolTip>Name of the argument in the EventArgs subclass constructor.</ToolTip>
<Default>propertyName</Default>
</Literal>
<Literal>
<ID>propertyName</ID>
<ToolTip>Name of the property in the EventArgs subclass.</ToolTip>
<Default>PropertyName</Default>
</Literal>
<Literal>
<ID>eventName</ID>
<ToolTip>Name of the event</ToolTip>
<Default>NameOfEvent</Default>
</Literal>
</Declarations>
<Code Language="CSharp"><![CDATA[public class $eventName$EventArgs : System.EventArgs
{
public $eventName$EventArgs($type$ $argName$)
{
this.$propertyName$ = $argName$;
}
public $type$ $propertyName$ { get; private set; }
}
public event EventHandler<$eventName$EventArgs> $eventName$;
protected virtual void On$eventName$($eventName$EventArgs e)
{
var handler = $eventName$;
if (handler != null)
handler(this, e);
}]]>
</Code>
<Imports>
<Import>
<Namespace>System</Namespace>
</Import>
</Imports>
</Snippet>
</CodeSnippet>
</CodeSnippets>
Run Code Online (Sandbox Code Playgroud)
这是一个有两个属性的:
<?xml version="1.0" encoding="utf-8" ?>
<CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
<CodeSnippet Format="1.0.0">
<Header>
<Title>Generic event with two types/arguments.</Title>
<Shortcut>ev2Generic</Shortcut>
<Description>Code snippet for event handler and On method</Description>
<Author>Ryan Lundy</Author>
<SnippetTypes>
<SnippetType>Expansion</SnippetType>
</SnippetTypes>
</Header>
<Snippet>
<Declarations>
<Literal>
<ID>type1</ID>
<ToolTip>Type of the first property in the EventArgs subclass.</ToolTip>
<Default>propertyType1</Default>
</Literal>
<Literal>
<ID>arg1Name</ID>
<ToolTip>Name of the first argument in the EventArgs subclass constructor.</ToolTip>
<Default>property1Name</Default>
</Literal>
<Literal>
<ID>property1Name</ID>
<ToolTip>Name of the first property in the EventArgs subclass.</ToolTip>
<Default>Property1Name</Default>
</Literal>
<Literal>
<ID>type2</ID>
<ToolTip>Type of the second property in the EventArgs subclass.</ToolTip>
<Default>propertyType1</Default>
</Literal>
<Literal>
<ID>arg2Name</ID>
<ToolTip>Name of the second argument in the EventArgs subclass constructor.</ToolTip>
<Default>property1Name</Default>
</Literal>
<Literal>
<ID>property2Name</ID>
<ToolTip>Name of the second property in the EventArgs subclass.</ToolTip>
<Default>Property2Name</Default>
</Literal>
<Literal>
<ID>eventName</ID>
<ToolTip>Name of the event</ToolTip>
<Default>NameOfEvent</Default>
</Literal>
</Declarations>
<Code Language="CSharp">
<![CDATA[public class $eventName$EventArgs : System.EventArgs
{
public $eventName$EventArgs($type1$ $arg1Name$, $type2$ $arg2Name$)
{
this.$property1Name$ = $arg1Name$;
this.$property2Name$ = $arg2Name$;
}
public $type1$ $property1Name$ { get; private set; }
public $type2$ $property2Name$ { get; private set; }
}
public event EventHandler<$eventName$EventArgs> $eventName$;
protected virtual void On$eventName$($eventName$EventArgs e)
{
var handler = $eventName$;
if (handler != null)
handler(this, e);
}]]>
</Code>
<Imports>
<Import>
<Namespace>System</Namespace>
</Import>
</Imports>
</Snippet>
</CodeSnippet>
</CodeSnippets>
Run Code Online (Sandbox Code Playgroud)
您可以按照模式使用任意数量的属性创建它们.