我理解使用标准MS事件处理程序委托签名的好处,因为它允许您轻松扩展通过事件传递的信息,而不会破坏任何基于旧委托签名的旧关系。
我想知道在实践中人们经常遵循这条规则吗?假设我有一个像这样的简单事件
public event NameChangedHandler NameChanged;
public delegate void NameChangedHandler(Object sender, string oldName, string newName);
这是一个简单的事件,我几乎肯定我从NameChanged事件中需要知道的唯一参数是名称已更改的对象,旧名称和新名称。那么创建一个单独的NameChangedEventArgs类是否值得,或者像这样的简单事件是否可以直接通过委托参数返回参数?
答案 0 :(得分:10)
为您的活动使用EventHandler<T>
通用代表,并创建从EventArgs
派生的类型来保存您的活动数据。换句话说,永远。当你碰到它时,你总是知道它是如何工作的,因为它从来没有这样做过。
编辑:
代码分析CA1003: Use generic event handler instances
代码分析CA1009: Declare event handlers correctly
答案 1 :(得分:6)
如果你是唯一一个必须处理它的人,你可以采取任何错误的方式。但是,学习标准并坚持使用这些标准并不是一个坏主意,以便在与他人合作时保持良好的习惯。
所以我会帮你做个交易。如果你保证以正确的方式做到这一点,我会给你一个代码片段,这样可以减轻痛苦。只需将其放在.snippet文件中,然后将该文件放入:
My Documents \ Visual Studio 2008 \ Code Snippets \ Visual C#\ My Code Snippets \\ (或Visual Studio 2005,如果适用)
这是片段;通过输入ev2Generic并点击Tab:
在VS中使用它<?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>Kyralessa</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>propertyType2</Default>
</Literal>
<Literal>
<ID>arg2Name</ID>
<ToolTip>Name of the second argument in the EventArgs subclass constructor.</ToolTip>
<Default>property2Name</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>
</Snippet>
</CodeSnippet>
</CodeSnippets>
答案 2 :(得分:4)
在实践中,人们常常会这样做 使用EventArgs派生类]。
我从未遇到过没有使用EventArgs派生类的时间。正如您自己所说,它会提高您以后更改代码的能力。我还认为可读性得到了改进,因为很容易看出这是一个事件处理程序。
创建一个单独的是否值得 NameChangedEventArgs类,或者用于 像这样的简单事件就是这样 只能归还 直接通过论证 委托论据?
你好像说你会将EventArgs用于具有更多参数的事件处理程序,而不是像这样的实例使用它。老实说,在C#编程时,这根本不是一个选项。一致性是必须的,特别是在今天的论坛世界,像开源项目等,很容易丢失它。当然,如果你是在摇滚下编程,你可以做任何你喜欢的事情,但更大的C#社区将感谢你遵循以下标准,特别是在代码中使用一致性。