قم بتمرير قيمة الإرجاع مرة أخرى من خلال EventHandler

StackOverflow https://stackoverflow.com/questions/1446256

  •  22-07-2019
  •  | 
  •  

سؤال

أحاول الكتابة إلى واجهة برمجة التطبيقات (API) وأحتاج إلى الاتصال بمعالج الأحداث عندما أحصل على بيانات من جدول.شيء من هذا القبيل:

    public override bool Run(Company.API api)
    {
        SomeInfo _someInfo = new SomeInfo();

        if (_someInfo.Results == 1)
            return true;
        else
            return false;

        using (MyTable table = new MyTable(api))
        {
            table.WhenData += new EventHandler<DataEventArgs<Record>>(table_WhenData);
            table.WhenDead += new EventHandler<EventArgs>(table_WhenDead);
            table.Start();
        }

    public void table_WhenData(object sender, DataEventArgs<Record> e)
    {
        return true;
    }

المشكلة التي أواجهها هي أنني لا أعرف كيفية تمرير قيمة الإرجاع مرة أخرى من table_WhenData إلى طريقة التشغيل.

لقد جربت العديد من الطرق (مثل محاولة تمرير _someInfo إلى الطريقة) ولكن يبدو أنني غير قادر على فهم بناء الجملة بشكل صحيح.

هو موضع تقدير كبير أي اقتراح.

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

المحلول

النمط الشائع هنا ليس إرجاع أي بيانات من معالج الحدث، ولكن إضافة خصائص إلى كائن وسيطة الحدث الخاص بك حتى يتمكن مستهلك الحدث من تعيين الخصائص التي يمكن للمتصل الوصول إليها بعد ذلك.وهذا أمر شائع جدًا في كود التعامل مع واجهة المستخدم؛ترى مفهوم إلغاء الحدث في كل مكان.

ما يلي هو رمز زائف، وليس جاهزًا للتجميع.والغرض منه هو إظهار النمط.

public MyEventArgs : EventArgs
{
   public bool Cancel{get;set;}
}

public bool fireEvent()
{
    MyEventArgs e=new MyEventArgs();

    //Don't forget a null check, assume this is an event
    FireEventHandler(this,e);

    return e.Cancel;
}

public HandleFireEvent(object sender, MyEventArgs e)
{
 e.Cancel=true;
}

يحرر

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

نصائح أخرى

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

في لالمعلن عن الحدث / الناشر:

// the delegate
public delegate string ReturnStringEventHandler(object sender, EventArgs args);
// the event
public event ReturnStringEventHandler StringReturnEvent;
// raise the event
protected void OnStringReturnEvent(EventArgs e)
    {
        if (StringReturnEvent != null)  // make sure at least one subscriber
              // note the event is returning a string
              string myString = StringReturnEvent(this, e);
    }

في المشترك الحدث:

// Subscribe to event, probably in class constructor / initializer method
StringReturnEvent += HandleStringReturnEvent;

// Handle event, return data
private string HandleStringReturnEvent(object sender, EventArgs e)
{
    return "a string to return";
}

و. NET مثالا على ذلك في الحدث AssemblyResolve، والذي يستخدم مندوب ResolveEventHandler لإرجاع البيانات، في هذه الحالة إشارة إلى الجمعية المرجوة. MSDN المادة على الحدث AssemblyResolve

ولقد استخدمت شخصيا كل من الحدث AssemblyResolve وتقنية مندوب مخصصة لإرجاع البيانات من حدث، وكلاهما عمل كما هو متوقع على البصرية ستوديو 2010.

والطريقة الوحيدة التي يمكن أن تفعل ذلك هو جعل واحدة من الحجج (يفضل أن يكون "وسائط" بدلا من المرسل) قابلة للتغيير. إذا لم تكن قابلة للتغيير بالفعل، كنت قد حصلت أساسا المشاكل - هناك فقط لا طريقة للحصول على المعلومات من

و(حسنا، هناك طريقة واحدة - هل يمكن أن تبقي على حجة الحدث في حد ذاته غير قابل للتغيير، ولكن تأكد عضو واحد من ذلك الطريقة التي ينتهي استدعاء مندوب مسجل عليها في قانون رفع الحدث في المقام الأول ولكن هذا أمر مروع ... .)

وهناك حل بسيط هو استخدام إغلاق:

public override bool Run() {
    SomeInfo someInfo = ...
    table.WhenData += (obj, args) => {
        someInfo.Return = something
    };
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top