문제

를 시작할 때마다 깊은 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; }
  }
}

나중에,나

public event EventHandler<Foo> FooChanged;

public event EventHandler<Bar> BarChanged;

그러나,그것은 보인다는 표준다.NET 를 만들어 새로운 대리인 EventArgs 서브 클래스의 각 유형을 위해 이벤트입니다.무언가 잘못된 내고 있는 일반적인 접근방식은?


편집:이 게시물을 내가 다시 만들어진 이에,새로운 프로젝트 있는지 확인하고 싶어 그것은 확인했습니다.실제로,다시 만드는 그것으로 나가 게시됩니다.내가 찾는 것이 일반 EventHandler<TEventArgs>, 다,그래서 당신을 만들 필요가 없는 일반적인 대리인,하지만 당신은 여전히 일반 EventArgs<T> 클래스,기 TEventArgs: EventArgs.
다른 편집:하나의 단점(나)의 내장 솔루션은 추가 verbosity:

public event EventHandler<EventArgs<Foo>> FooChanged;

public event EventHandler<Foo> FooChanged;

그것은 고통이 될 수 있습을 위해 고객 등록을 위한 당신의 이벤트이지만,때문에 시스템이 기본적으로 네임스페이스를 가져온다,그래서 그들은 그들을 수동으로 추구하는 네임스페이스,도와 멋진 도구는 다음과 같---끝---이력서 내...사람이 어떤 아이디어에 관한가?

도움이 되었습니까?

해결책

.NET Framework 2.0 이후 다음 양식의 대표가 추가되었습니다.

public delegate void EventHandler<TArgs>(object sender, TArgs args) where TArgs : EventArgs

단일 데이터 항목이있는 EventArgs에 대한 기본 구현을 제공하기 때문에 접근 방식은 조금 더 나아갑니다. 그러나 원래 아이디어의 여러 속성이 부족합니다.

  1. 종속 코드를 변경하지 않고는 이벤트 데이터에 더 많은 속성을 추가 할 수 없습니다. 이벤트 가입자에게 더 많은 데이터를 제공하려면 대의원 서명을 변경해야합니다.
  2. 데이터 객체는 일반적이지만 "익명"이기도하며 코드를 읽는 동안 사용법에서 "항목"속성을 해독해야합니다. 제공하는 데이터에 따라 명명되어야합니다.
  3. 이 방법으로 제네릭을 사용하면 기본 (항목) 유형의 계층 구조가있을 때 Eventargs의 병렬 계층 구조를 만들 수 없습니다. 예를 들어 Eventargsu003CBaseType> EventArgs의 기본 유형이 아닙니다u003CDerivedType> BaseType이 DevivedType의 기본이더라도.

그래서 나는 일반적인 이벤트 핸들러를 사용하는 것이 더 낫다고 생각합니다.u003CT> 그러나 여전히 데이터 모델의 요구 사항에 따라 구성된 사용자 정의 EventArgs 클래스가 있습니다. Resharper와 같은 Visual Studio 및 Extensions를 사용하면 이와 같은 새로운 클래스를 만드는 것은 몇 가지 명령의 문제 일뿐입니다.

다른 팁

하는 일반적인 이벤트 선언을 더 쉽게 만들고,부부의 코드 조각한다.를 사용:

  • 복사본을 전체 조각.
  • 에 붙여넣을 텍스트 파일(예를들면메모장에서).
  • 으로 파일을 저장합니다.조각에 확장자.
  • 습니다.조각에서 파일을 적절한 조각 같은 디렉토리:

Visual Studio2008\코드 조각\Visual C#\내 코드 조각

여기에는 한 사용하는 사용자 지정시키려면 다음으로 클래스 하나의 속성:

<?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>Kyralessa</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>
        </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>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>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>
    </Snippet>
  </CodeSnippet>
</CodeSnippets>

할 수 있는 패턴을 따라 만들어진 만큼 속성을 같습니다.

아니, 나는 이것이 잘못된 접근법이라고 생각하지 않습니다. [Fantastic] 책에서 권장 된 것 같아요 프레임 워크 설계 지침. 나도 같은 일을한다.

이것은 올바른 구현입니다. 제네릭이 처음 제공 (2.0)가 제공되었으므로 .NET 프레임 워크 (MSCORLIB)에 추가되었습니다.

사용 및 구현에 대한 자세한 내용은 MSDN을 참조하십시오. http://msdn.microsoft.com/en-us/library/db0etb8x.aspx

이 작은 패턴을 처음 보았을 때 나는 복합 UI 애플리케이션 블록, MS Patterns & Practices Group에서.

그것은 나에게 적기를 던지지 않습니다. 실제로 그것은 제네릭을 이용하기 위해 가장 현명한 방법입니다. 마른 규칙.

.NET 2.0 이후

EventHandler<T>

구현되었습니다.

MSDN에서 일반 이벤트 핸들러를 찾을 수 있습니다 http://msdn.microsoft.com/en-us/library/db0etb8x.aspx

나는 일반적인 이벤트 핸들러를 광범위하게 사용하고 있었고 소위 "유형 (클래스) 폭발"프로젝트가 더 작고 탐색하기가 더 쉬워지는 것을 방지 할 수있었습니다.

새로운 직관적 인 이벤트 핸드러 대의원 대의원을위한 새로운 직관적 인 대의원을 제시하는 것은 고통스럽고 기존 유형의 부여 "*eventhandler"에 대한 새로운 대표 이름에 겹치는 것은 내 의견으로는 큰 도움이되지 않습니다.

최근 버전의 .NET에는 그러한 이벤트 핸들러가 정의되어 있다고 생각합니다. 그것은 내가 염려하는 한 큰 엄지 손가락입니다.

/편집하다

원래 그 차이를 얻지 못했습니다. Eventargs에서 물려받는 수업을 다시 전달하는 한 문제가 없습니다. 당신이 유지 관리 가능성 이유에 대해 결과를 감싸지 않았다면 걱정할 것입니다. 나는 여전히 그것이 나에게 좋아 보인다고 말한다.

일반 이벤트 핸들러 인스턴스를 사용하십시오

.NET Framework 2.0 이전에 사용자 정의 정보를 이벤트 핸들러에 전달하기 위해 System.eventArgs 클래스에서 파생 된 클래스를 지정한 새로운 대표를 선언해야했습니다. .NET에서는 더 이상 사실이 아닙니다

시스템을 소개 한 프레임 워크 2.0u003CT> ) 대표. 이 일반 대의원을 사용하면 Eventargs에서 파생 된 모든 클래스가 이벤트 핸들러와 함께 사용할 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top