Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/307.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# .NET事件处理程序-通用还是否?_C#_.net_Generics_Events - Fatal编程技术网

C# .NET事件处理程序-通用还是否?

C# .NET事件处理程序-通用还是否?,c#,.net,generics,events,C#,.net,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) {

每次我开始深入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; }
  }
}
vs

公共事件事件处理程序已更改;

但是,客户端注册您的事件可能会很痛苦,因为系统名称空间在默认情况下是导入的,所以他们必须手动查找您的名称空间,即使使用像Resharper这样的高级工具。。。有人对此有什么想法吗?

没有,我不认为这是一种错误的方法。我认为它甚至在这本书中被推荐。我也这么做。

我确实相信.NET的最新版本中定义了这样一个事件处理程序。就我而言,这是一个大拇指

/编辑


本来就没有区别。只要您传回一个从EventArgs继承的类,我看不出有什么问题。如果您没有出于可维护性的原因包装结果,我会很担心。我还是说它看起来不错。

这是正确的实现。自从泛型首次出现(2.0)以来,它就被添加到.NET Framework(mscorlib)中

有关其用法和实现的更多信息,请参见MSDN:

自.NET 2.0以来

EventHandler


已经实现。

第一次看到这个小模式时,我使用的是MS模式与实践小组的模式


它不会向我扔任何红旗;事实上,这甚至是一种利用泛型来遵循规则的聪明方法。

您可以在MSDN上找到泛型EventHandler

我一直在广泛使用泛型EventHandler,能够防止所谓的“类型(类)爆炸” 该项目被保持在更小的范围内,并且更易于导航

为非泛型EventHandler委托设计一个新的直观的委托是一件痛苦的事情,并且与现有类型重叠
在我看来,将“*EventHandler”添加到新的委托名称并没有多大帮助

自.NET Framework 2.0以来,已添加了以下形式的委托

public delegate void EventHandler<TArgs>(object sender, TArgs args) where TArgs : EventArgs
public委托void EventHandler(对象发送方,targets args),其中targets:EventArgs
您的方法更进一步,因为您为带有单个数据项的EventArgs提供了开箱即用的实现,但它缺少原始想法的几个属性:

  • 如果不更改依赖代码,则无法向事件数据添加更多属性。您必须更改委托签名以向事件订阅服务器提供更多数据
  • 您的数据对象是泛型的,但它也是“匿名的”,在读取代码时,您必须从用法中解密“Item”属性。它应该根据它提供的数据命名
  • 以这种方式使用泛型,当您具有底层(项)类型的层次结构时,您无法使EventArgs具有并行层次结构。例如,EventArgs不是EventArgs的基类型,即使BaseType是DerivedType的基类型
    因此,我认为最好使用泛型EventHandler,但仍然有自定义EventArgs类,根据数据模型的要求进行组织。对于VisualStudio和ReSharper之类的扩展,创建这样的新类只需几个命令

    为了使通用事件声明更容易,我为它创建了几个代码段。要使用它们:

    • 复制整个片段
    • 将其粘贴到文本文件中(例如,在记事本中)
    • 使用.snippet扩展名保存文件
    • 将.snippet文件放在适当的代码段目录中,例如:
    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>
    
    
    具有一个类型/参数的泛型事件。
    EV1基因
    事件处理程序和方法的代码段
    莱恩·伦迪
    膨胀
    类型
    EventArgs子类中属性的类型。
    属性类型
    argName
    EventArgs子类构造函数中参数的名称。
    属性名称
    属性名称
    EventArgs子类中属性的名称。
    属性名
    事件名
    活动名称
    事件名称
    $eventName$;
    $eventName$($eventName$EventArgs e)上受保护的虚拟空间
    {
    变量处理程序=$eventName$;
    if(处理程序!=null)
    处理者(本,e);
    }]]>
    
    系统
    
    这里有一个有两个属性:

    <?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>
    
    
    具有两种类型/参数的泛型事件。
    EV2通用
    事件处理程序和方法的代码段
    莱恩·伦迪
    膨胀
    类型1
    EventArgs子类中第一个属性的类型。
    属性类型1
    arg1名称
    EventArgs子类构造函数中第一个参数的名称。
    物业名称
    物业名称
    EventArgs子类中第一个属性的名称。
    物业名称
    类型2
    EventArgs子类中第二个属性的类型。
    属性类型1
    arg2名称
    EventArgs子类构造函数中第二个参数的名称。
    物业名称
    物业名称
    EventArgs子类中第二个属性的名称。
    物业名称
    事件名
    活动名称
    事件名称
    
    
    public delegate void EventHandler<TArgs>(object sender, TArgs args) where TArgs : 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>
    
    <?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>