创建没有标准(Obj sender、EventArgs args)签名的事件处理程序委托有多么错误?

发布于 2024-07-27 01:43:19 字数 424 浏览 7 评论 0原文

我了解使用标准 MS 事件处理程序委托签名的好处,因为它允许您轻松扩展通过事件传递的信息,而不会破坏基于旧委托签名的任何旧关系。

我想知道在实践中人们遵循这条规则的频率如何? 假设我有一个像这样的简单事件

public event NameChangedHandler NameChanged;
public delegate void NameChangedHandler(Object sender, string oldName, string newName);

这是一个简单的事件,而且我几乎肯定我需要从 NameChanged 事件中知道的唯一参数是名称更改的对象、旧名称和新名称姓名。 那么是否值得创建一个单独的 NameChangedEventArgs 类,或者对于像这样的简单事件,直接通过委托参数返回参数是否可以接受?

I understand the benefits of using the standard MS event handler delegate signature as it allows you to easily expand on the information passed through the event with out breaking any old relationships that are based on the old delegate signature.

What I'm wondering is in practice how often do people follow this rule? Say I have a simple event like this

public event NameChangedHandler NameChanged;
public delegate void NameChangedHandler(Object sender, string oldName, string newName);

It's a simple event, and I'm nearly positive that the only arguments I'm ever going to need to know from the NameChanged event is the object whose name changed, the old name, and the new name. So is it worth it to create a separate NameChangedEventArgs class, or for simple events like this is it acceptable to just return the the arguments directly through the delegate arguments?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

乙白 2024-08-03 01:43:19

对您的事件使用 EventHandler 通用委托,并创建从 EventArgs 派生的类型来保存您的事件数据。 换句话说,总是如此。 当你遇到它时,你总是知道它是如何工作的,因为它从来没有这样做过。

编辑:

代码分析CA1003:使用通用事件处理程序实例
代码分析CA1009:正确声明事件处理程序

Use the EventHandler<T> generic delegates for your events and create a type derived from EventArgs to hold your event data. So in other words, always. It's something that you always know exactly how it works when you come across it because it's never done otherwise.

Edit:

Code analysis CA1003: Use generic event handler instances
Code analysis CA1009: Declare event handlers correctly

爱的故事 2024-08-03 01:43:19

如果你是唯一必须处理一件事的人,那么你可能会以错误的方式做任何事情。 但学习标准并遵守它们并不是一个坏主意,这样您在与他人一起编写代码时就能保持良好的习惯。

所以我会和你做一笔交易。 如果您保证以正确的方式进行操作,我会给您一个代码片段,以减轻您的痛苦。 只需将其放入 .snippet 文件中,然后将该文件放入:

My Documents\Visual Studio 2008\Code Snippets\Visual C#\My Code Snippets\
(或 Visual Studio 2005,如果适用)

这是代码片段; 在 VS 中输入 ev2Generic 并按 Tab 键即可使用它:

<?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>

You can do anything the wrong way if you're the only one who has to deal with it. But it's not a bad idea to learn standards and stick to them so that you keep good habits when you're working on code with others.

So I'll make you a deal. If you promise to do it the right way, I'll give you a code snippet that'll make it much less of a pain. Just put this in a .snippet file, and put that file in:

My Documents\Visual Studio 2008\Code Snippets\Visual C#\My Code Snippets\
(or Visual Studio 2005 if applicable)

And here's the snippet; use it in VS by typing ev2Generic and hitting Tab:

<?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>
故事灯 2024-08-03 01:43:19

在实践中,人们[不
使用 EventArgs 派生类]。

我从来没有遇到过不使用EventArgs派生类的时候。 正如您自己所说,它提高了您以后更改代码的能力。 我还认为可读性得到了提高,因为很容易看出这是一个事件处理程序。

是否值得创建一个单独的
NameChangedEventArgs 类,或用于
简单的事件就是这样
可以接受只返回
直接通过参数
委托参数?

您似乎说您会使用 EventArgs 来处理具有更多参数的事件处理程序,而不是将其用于这样的实例。 老实说,在使用 C# 编程时,这根本不是一个选择。 一致性是必须的,尤其是在当今的论坛、开源项目等领域,很容易失去一致性。 当然,如果您正在秘密编程,您可以做任何您喜欢的事情,但是更大的 C# 社区将感谢您遵循标准,尤其是在代码中使用一致性。

In practice how often do people [not
use EventArgs derived classes].

I have never encountered a time when EventArgs derived classes have not been used. As you say yourself, it increases your ability to change your code later. I would also argue that the readability is improved, since it's easy to see that this is an event handler.

Is it worth it to create a separate
NameChangedEventArgs class, or for
simple events like this is it
acceptable to just return the
arguments directly through the
delegate arguments?

You seem to say that you would use EventArgs for event handlers with more params and not use it for instances like this. Honestly, that is simply not an option when programming in C#. Consistency is a must, especially in today's world of forum's like this, open source projects, etc where it's easy to lose it. Sure if you are programming this under a rock, you may do whatever you like, but the greater C# community will thank you for following standards and especially using consistency in you code.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文