সি #: উত্তরাধিকার সূত্রে প্রাপ্ত ঘটনা উত্থাপন


144

আমার একটি বেস ক্লাস রয়েছে যাতে নিম্নলিখিত ইভেন্টগুলি রয়েছে:

public event EventHandler Loading;
public event EventHandler Finished;

এই বেস বর্গ থেকে উত্তরাধিকারসূত্রে প্রাপ্ত একটি শ্রেণিতে আমি ইভেন্টটি বাড়ানোর চেষ্টা করি:

this.Loading(this, new EventHandler()); // All we care about is which object is loading.

আমি নিম্নলিখিত ত্রুটিটি পেয়েছি:

ইভেন্ট 'বেসক্লাস। লোডিং' কেবলমাত্র + = বা - = (বেসক্লাস ') এর বাম দিকে প্রদর্শিত হতে পারে

আমি ধরে নিচ্ছি যে আমি এই ইভেন্টগুলি অন্যান্য উত্তরাধিকারী সদস্যদের মতো অ্যাক্সেস করতে পারি না?


এই প্রশ্নের উত্তর ইতিমধ্যে ফ্রেডেরিক ঘেইসেলস দিয়েছিলেন । একই অনুশীলনটি মাইক্রোসফ্ট ডক্সে প্রস্তাবিত: ডেরিভড ক্লাসে বেস ক্লাস ইভেন্টগুলি কীভাবে বাড়ানো যায় (সি # প্রোগ্রামিং গাইড) অফিসিয়াল "সি # প্রোগ্রামিং গাইড" হিসাবে
এলিয়াহু অ্যারন

উত্তর:


160

আপনার যা করতে হবে তা হ'ল:

আপনার বেস ক্লাসে (যেখানে আপনি ইভেন্টগুলি ঘোষণা করেছেন) সুরক্ষিত পদ্ধতিগুলি তৈরি করুন যা ইভেন্টগুলি বাড়াতে ব্যবহার করা যেতে পারে:

public class MyClass
{
   public event EventHandler Loading;
   public event EventHandler Finished;

   protected virtual void OnLoading(EventArgs e)
   {
       EventHandler handler = Loading;
       if( handler != null )
       {
           handler(this, e);
       }
   }

   protected virtual void OnFinished(EventArgs e)
   {
       EventHandler handler = Finished;
       if( handler != null )
       {
           handler(this, e);
       }
   }
}

(নোট করুন যে আপনার ইভেন্ট হ্যান্ডেলারটি চালানো উচিত কিনা তা পরীক্ষা করার জন্য আপনার সম্ভবত সেই পদ্ধতিগুলি পরিবর্তন করা উচিত)।

তারপরে, এই বেস শ্রেণীর উত্তরাধিকারী ক্লাসগুলিতে, ইভেন্টগুলি উত্থাপনের জন্য আপনি কেবলমাত্র অনফিনিশ বা অনলয়েডিং পদ্ধতিতে কল করতে পারেন:

public AnotherClass : MyClass
{
    public void DoSomeStuff()
    {
        ...
        OnLoading(EventArgs.Empty);
        ...
        OnFinished(EventArgs.Empty);
    }
}

5
অন্যথায় কিছু করার কারণ না থাকলে এই পদ্ধতিগুলিকে ভার্চুয়াল সুরক্ষিত করা উচিত।
ম্যাক্স শ্মেলিং

6
এটি ভার্চুয়াল হওয়া উচিত কেন? আমি উত্তরাধিকারীরা যদি ইভেন্টটি
উত্থাপনের পদ্ধতিটি

4
অফিসিয়াল নির্দেশিকা: msdn.microsoft.com/en-us/library/w369ty8x(VS.80).aspx
meandmycode

5
পদ্ধতিটি ভার্চুয়াল তৈরির বিষয়ে, যাতে উত্তরাধিকারীরা ইভেন্টের অনুরোধের আচরণকে ওভাররাইড করতে পারে: আপনি যে পরিস্থিতিটি প্রয়োজনীয় ছিলেন সেখানে আপনি কতবার ছিলেন? তার পরে; ওভারডেন পদ্ধতিতে, আপনি ইভেন্টটি বাড়িয়ে তুলতে পারবেন না, যেহেতু আপনি টিএস দ্বারা উল্লিখিত হিসাবে একই ত্রুটি পাবেন।
ফ্রেডেরিক গেইসেলস 14

2
@ ভেরাক্স আমি এটিকে অনুসরণ করি কারণ যুক্তিটি সঠিক, আমি কোডটি কীভাবে পুনরায় ব্যবহারযোগ্য এবং এক্সটেনসিবল আশা করি তার উপর নির্ভর করে, আমি এটিটির ব্যাক করার জন্য সরকারী দিকনির্দেশনা সরবরাহ করেছি .. লেখার সময় আপনাকে। নেট ভেরাক্সও খুব নতুন বলে মনে হয় সুতরাং এটি একটু বিস্মিত হওয়ার মতো যে আপনি আমার 7 বছরের অভিজ্ঞতার সাথে একমত হওয়ার জন্য এটি খনন করেছেন
meandmycode

123

আপনি ডিক্লেয়ারিং ক্লাসে কেবলমাত্র একটি ইভেন্ট অ্যাক্সেস করতে পারবেন, যেমন .NET প্রকৃত প্রতিনিধিকে ধারণ করে এমন পর্দার পিছনে ব্যক্তিগত নজির ভেরিয়েবল তৈরি করে। এটা করছি..

public event EventHandler MyPropertyChanged;

আসলে এটি করছে;

private EventHandler myPropertyChangedDelegate;

public event EventHandler MyPropertyChanged
{
    add { myPropertyChangedDelegate += value; }
    remove { myPropertyChangedDelegate -= value; }
}

এবং এই করছেন ...

MyPropertyChanged(this, EventArgs.Empty);

আসলে কি এই ...

myPropertyChangedDelegate(this, EventArgs.Empty);

সুতরাং আপনি (স্পষ্টতই) ঘোষক শ্রেণীর মধ্যে থেকে কেবল প্রাইভেট ডেলিগেটের উদাহরণ পরিবর্তনযোগ্য অ্যাক্সেস করতে পারেন।

কনভেনশন হ'ল ঘোষিত শ্রেণিতে এই জাতীয় কিছু সরবরাহ করা ..

protected virtual void OnMyPropertyChanged(EventArgs e)
{
    EventHandler invoker = MyPropertyChanged;

    if(invoker != null) invoker(this, e);
}

এরপরে OnMyPropertyChanged(EventArgs.Empty)আপনি সেই ক্লাসের যে কোনও জায়গা থেকে বা উত্তরাধিকারের উত্তরাধিকারের নীচে ইভেন্টটি শুরু করতে কল করতে পারেন ।


আমি এই ... বাস্তবায়নে কিছু সমস্যা ছিল stackoverflow.com/q/10593632/328397
goodguys_activate

আমি এই উত্তরটিকে অগ্রাধিকার দিচ্ছি কারণ এটি ব্যাখ্যা করে কেন আপনার কেবলমাত্র পদ্ধতির পরিবর্তে পদ্ধতির ব্যবহার করতে হবে। চমৎকার কাজ.
কাউবয়দান

8

আমি ধরে নিচ্ছি যে আমি এই ইভেন্টগুলি অন্যান্য উত্তরাধিকারী সদস্যদের মতো অ্যাক্সেস করতে পারি না?

অবিকল। উত্তরাধিকার সূত্রে প্রাপ্ত শ্রেণি থেকে উত্থাপন সক্ষম করার জন্য বেস ক্লাসে প্রতিটি ইভেন্টের জন্য কোনও সুরক্ষিত ফাংশন প্রদান OnXyzবা RaiseXyzপ্রতিটি ইভেন্টের জন্য এটি রীতিগত । উদাহরণ স্বরূপ:

public event EventHandler Loading;

protected virtual void OnLoading() {
    EventHandler handler = Loading;
    if (handler != null)
        handler(this, EventArgs.Empty);
}

উত্তরাধিকারী শ্রেণিতে ডাকা:

OnLoading();

0

আপনি এইভাবে চেষ্টা করতে পারেন, এটি আমার পক্ষে কাজ করে:

public delegate void MyEventHaldler(object sender, EventArgs e);

public class B
{
    public virtual event MyEventHaldler MyEvent;
    protected override void OnChanged(EventArgs e)
    {
        if (MyEvent != null)
            MyEvent(this, e);
    }
}

public class D : B
{
    public override event MyEventHaldler MyEvent;
    protected override void OnChanged(EventArgs e)
    {
        if (MyEvent != null)
            MyEvent(this, e);
    }
}

2
নোট করুন যে এই নিবন্ধটি ভার্চুয়াল ইভেন্টগুলি ঘোষণার বিরুদ্ধে এবং সেগুলি ওভাররাইড করার বিরুদ্ধে সতর্ক করেছে যেহেতু এটি দাবি করে যে সংকলকটি
পাবলিক ওয়্যারলেস

0

কোনও পুরানো থ্রেডকে পুনরুত্থিত করার জন্য নয় তবে যদি কেউ খুঁজছেন তবে আমি যা করেছি তা ছিল

protected EventHandler myPropertyChangedDelegate;

public event EventHandler MyPropertyChanged
{
    add { myPropertyChangedDelegate += value; }
    remove { myPropertyChangedDelegate -= value; }
}

এটি আপনাকে ইভেন্টটি একটি উদ্ভূত শ্রেণিতে উত্তরাধিকারী করতে দেয় যাতে আপনি + = বাক্য গঠন রেখে পদ্ধতিটি মোড়ানোর প্রয়োজন ছাড়াই এটি শুরু করতে পারেন। আমি অনুমান করি যে আপনি যদি এখনও এটি করেন তবে মোড়ানো পদ্ধতিগুলি সহ এটি করতে পারেন

public event EventHandler MyPropertyChanged
{
   add { AddDelegate(value); }
   remove { RemoveDelegate(value); }
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.