سؤال

في كل مرة أبدأ في عميق في مشروع 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;

ومع ذلك ، يبدو أن معيار .صافي هو خلق تفويض جديد ، EventArgs فرعية لكل نوع من الحدث.هل هناك شيء خاطئ مع عامة النهج ؟


تحرير:والسبب في هذا المنصب هو أن أنا فقط إعادة إنشاء هذا المشروع الجديد ، ومن أراد التأكد من ذلك كان حسنا.في الحقيقة كنت إعادة خلق له كما نشر.وجدت أن هناك مجموعة عامة EventHandler<TEventArgs>, لذلك أنت لا تحتاج إلى إنشاء مندوب عام ولكن كنت لا تزال بحاجة العامة EventArgs<T> الدرجة, لأن TEventArgs: EventArgs.
آخر تحرير:الجانب السلبي واحد (لي) من المدمج في حل إضافية الإسهاب:

public event EventHandler<EventArgs<Foo>> FooChanged;

مقابل

public event EventHandler<Foo> FooChanged;

يمكن أن يكون الألم للعملاء التسجيل في الأحداث الخاصة بك على الرغم لأن النظام مساحة المستوردة بشكل افتراضي ، ولذلك يجب أن يدويا البحث عن مساحة الاسم الخاصة بك ، حتى مع الهوى أداة مثل Resharper...أي شخص لديه أي أفكار تتعلق بذلك ؟

هل كانت مفيدة؟

المحلول

مندوب النموذج التالي تم إضافتها منذ ذلك الحين .NET Framework 2.0

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

كنت نهج يذهب أبعد قليلا ، منذ أن توفر الخروج من مربع لتنفيذ EventArgs مع بيانات واحد البند ، لكنها تفتقر إلى العديد من الخصائص من الفكرة الأصلية:

  1. لا يمكنك إضافة المزيد من الخصائص بيانات الحدث من دون تغيير تعتمد التعليمات البرمجية.سوف تضطر إلى تغيير تفويض التوقيع على توفير المزيد من البيانات إلى الحدث المشترك.
  2. البيانات الخاصة بك كائن عامة ، ولكنها أيضا "مجهول" ، أثناء قراءة الكود الذي سوف تضطر إلى فك "البند" المنشأة من الأعراف.ينبغي أن يكون اسمه وفقا للبيانات التي يقدمها.
  3. باستخدام الأدوية بهذه الطريقة لا يمكنك جعل متدرجة من EventArgs, عندما يكون لديك الهرمي الأساسية (البند) أنواع.E. g.EventArgs<BaseType> ليست قاعدة نوع EventArgs<DerivedType>حتى لو BaseType هو قاعدة DerivedType.

لذا أعتقد أنه من الأفضل استخدام عامة EventHandler<T>ولكن لا تزال لديها مخصص EventArgs الطبقات ، نظمت وفقا لمتطلبات نموذج البيانات.مع Visual Studio و ملحقات مثل ReSharper, أنها ليست سوى مسألة من عدد قليل من الأوامر لإنشاء فئة جديدة مثل ذلك.

نصائح أخرى

لجعل عامة الحدث الإعلان أسهل ، أنا خلق زوجين من التعليمات البرمجية المتكررة لذلك.استخدامها:

  • نسخ كل قصاصة.
  • لصقه في ملف نصي (مثلفي المفكرة).
  • حفظ الملف .مقتطف التمديد.
  • وضعت .مقتطف من الملفات الخاصة بك في المناسبة مقتطف دليل ، مثل:

Visual Studio 2008\مقتطفات الشفرة\Visual C#\My التعليمات البرمجية المتكررة

هنا هو واحد يستخدم مخصص 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>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>

يمكنك اتباع نمط لخلق لهم مع العديد من الخصائص كما تريد.

لا, أنا لا أعتقد أن هذا هو نهج خاطئ.أعتقد أنه حتى الموصى بها في [رائعة] كتاب إطار المبادئ التوجيهية تصميم.أنا أفعل نفس الشيء.

هذا هو التنفيذ الصحيح.وقد أضيفت إلى .NET Framework (mscorlib) منذ الأدوية الأولى جاء المتاحة (2.0).

لمزيد من المعلومات حول استخدام وتنفيذ راجع MSDN: http://msdn.microsoft.com/en-us/library/db0etb8x.aspx

أول مرة رأيت هذا الصغير نمط, كنت تستخدم مركب واجهة المستخدم التطبيق كتلة, من MS أنماط & الممارسات المجموعة.

لا رمي أي العلم الأحمر بالنسبة لي ، في واقع الأمر هو حتى طريقة ذكية للاستفادة من الأدوية لمتابعة الجافة القاعدة.

منذ .NET 2.0

EventHandler<T>

قد تم تنفيذها.

يمكنك أن تجد عامة EventHandler على MSDN http://msdn.microsoft.com/en-us/library/db0etb8x.aspx

لقد تم استخدام عامة EventHandler على نطاق واسع و كان قادرا على منع ما يسمى "الانفجار من نوع(فئات)" المشروع كان يحتفظ أصغر و أسهل للتنقل في جميع أنحاء.

يأتي مع بديهية مندوب عن غير عامة EventHandler مؤلمة والتداخل مع الأنواع الموجودة إلحاق "*EventHandler" الجديدة مندوب اسم لا يساعد كثيرا في رأيي

أعتقد أن الإصدارات الأخيرة من .صافي فقط مثل هذا الحدث معالج المحددة فيها.هذا ممتاز كبيرة بقدر ما انا قلق.

/تحرير

لم تحصل على التمييز هناك أصلا.طالما كنت تمر مرة أخرى فئة يرث من EventArgs التي كنت لا أرى مشكلة.سأكون قلقا إذا لم يلف resultfor الصيانة الأسباب.أنا ما زلت أقول أنها تبدو جيدة على لي.

استخدام عامة معالج الحدث الحالات

قبل .NET Framework 2.0 من أجل تمرير المعلومات المخصصة إلى معالج الحدث الجديد مندوب قد أعلنت أن تحديد فئة مشتقة من النظام.EventArgs الدرجة.هذا لم يعد صحيحا .صافي

Framework 2.0 التي أدخلت على النظام.EventHandler<T>) مندوب.هذا مندوب عام يسمح لأي فئة مشتقة من EventArgs ليتم استخدامها مع معالج الحدث.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top