সি # তে ইভেন্ট এবং ইভেন্ট হ্যান্ডলারগুলি বোঝা


329

আমি ইভেন্টগুলির উদ্দেশ্য বুঝতে পারি, বিশেষত ব্যবহারকারীর ইন্টারফেস তৈরির প্রসঙ্গে। আমি মনে করি এটি একটি ইভেন্ট তৈরির মূল প্রতিপাদ্য:

public void EventName(object sender, EventArgs e);

ইভেন্ট হ্যান্ডলাররা কী করে, কেন তাদের প্রয়োজন হয় এবং আমি কীভাবে এটি তৈরি করব?


9
@ অ্যান্ডি দ্বারা উল্লিখিত হিসাবে, এখানে কোড স্নিপেট ইভেন্টটিতে নিবন্ধিত পদ্ধতিটি বর্ণনা করে, ইভেন্টটি নয়।
dthrasher


উত্তর:


660

ইভেন্ট হ্যান্ডলারগুলি বুঝতে আপনার প্রতিনিধিদের বুঝতে হবে । ইন সি # , আপনি একটি পদ্ধতি একটি পয়েন্টার (অথবা একটি রেফারেন্স) হিসাবে একটি প্রতিনিধি মনে করতে পারেন। এটি দরকারী কারণ পয়েন্টারটি একটি মান হিসাবে প্রায় পাস হতে পারে।

প্রতিনিধিটির কেন্দ্রীয় ধারণাটি তার স্বাক্ষর বা আকার। এটি (1) রিটার্নের ধরণ এবং (2) ইনপুট আর্গুমেন্ট। উদাহরণস্বরূপ, যদি আমরা একটি প্রতিনিধি তৈরি void MyDelegate(object sender, EventArgs e), এটি শুধুমাত্র পদ্ধতি যা রিটার্ন নির্দেশ করতে পারেন void, এবং একটি নিতে objectএবং EventArgs। স্কোয়ার হোল এবং স্কোয়ার পেগের মতো। সুতরাং আমরা বলি এই পদ্ধতিগুলির প্রতিনিধি হিসাবে একই স্বাক্ষর, বা আকার রয়েছে।

সুতরাং কোনও পদ্ধতির রেফারেন্স কীভাবে তৈরি করা যায় তা জেনে, আসুন ইভেন্টগুলির উদ্দেশ্য সম্পর্কে ভাবা যাক: সিস্টেমে অন্য কোথাও কিছু ঘটলে আমরা কিছু কোড কার্যকর করতে পারি - বা "ইভেন্টটি পরিচালনা করি"। এটি করার জন্য, আমরা কোডটি কার্যকর করতে চাই তার জন্য নির্দিষ্ট পদ্ধতি তৈরি করি create ইভেন্ট এবং সম্পাদনের পদ্ধতিগুলির মধ্যে আঠালো প্রতিনিধিরা। ইভেন্টটি উত্থাপিত হওয়ার সময় কল করার পদ্ধতিগুলির জন্য পয়েন্টারগুলির একটি "তালিকা" অবশ্যই অভ্যন্তরীণভাবে অবশ্যই সঞ্চয় করতে হবে * আমরা প্রতিনিধিটিকে ইভেন্ট এবং ডাকা হবে এমন সমস্ত নির্দিষ্ট পদ্ধতির মধ্যে "চুক্তি" হিসাবে ব্যবহার করি।

সুতরাং ডিফল্ট EventHandler(এবং এটির মতো অনেকগুলি) পদ্ধতির একটি নির্দিষ্ট আকারকে (আবার শূন্য / অবজেক্ট-ইভেন্টআর্গস) উপস্থাপন করে। আপনি যখন কোনও ইভেন্ট ঘোষণা করেন, আপনি বলছেন যে কোনও রূপের পদ্ধতি (ইভেন্টহ্যান্ডলার) কোনও প্রতিনিধি নির্দিষ্ট করে সেই ইভেন্টটি কীভাবে আহবান করবে:

//This delegate can be used to point to methods
//which return void and take a string.
public delegate void MyEventHandler(string foo);

//This event can cause any method which conforms
//to MyEventHandler to be called.
public event MyEventHandler SomethingHappened;

//Here is some code I want to be executed
//when SomethingHappened fires.
void HandleSomethingHappened(string foo)
{
    //Do some stuff
}

//I am creating a delegate (pointer) to HandleSomethingHappened
//and adding it to SomethingHappened's list of "Event Handlers".
myObj.SomethingHappened += new MyEventHandler(HandleSomethingHappened);

//To raise the event within a method.
SomethingHappened("bar");

(* এটি নেট। এর ইভেন্টগুলির মূল চাবিকাঠি এবং "যাদু" কে ছুঁড়ে ফেলেছে - একটি ইভেন্ট সত্যিই কভারের নীচে, একই "আকৃতির" পদ্ধতির কেবলমাত্র একটি তালিকা the ইভেন্টটি যেখানে থাকে সেখানে সংরক্ষণ করা হয় When কখন ইভেন্টটি "উত্থাপিত" হয়েছে, এটি সত্যই কেবল "পদ্ধতিগুলির এই তালিকার মধ্য দিয়ে যান এবং এই মানগুলিকে প্যারামিটার হিসাবে ব্যবহার করে" একে একে কল করুন an ইভেন্ট হ্যান্ডলারের দায়িত্ব দেওয়া কেবল পদ্ধতির তালিকায় আপনার পদ্ধতিটি যুক্ত করার সহজ উপায়, সহজ উপায় ডাকা হবে).


24
এবং এখন কেউ ব্যাখ্যা করতে পারে কেন ইভেন্টটিকে ইভেন্টহ্যান্ডলার বলা হয় ?? সমস্ত বিভ্রান্তিকর নামকরণের কনভেনশনগুলির মধ্যে, এটি সবচেয়ে খারাপ ...
জোয়েল

37
@ জোয়েল ইন গো ইভেন্টটিকে ইভেন্টহ্যান্ডলার বলা হয় না - ইভেন্ট হ্যান্ডলারটি হ'ল চুক্তি হ'ল ইভেন্টটি যার সাথে যোগাযোগ করবে তার সাথে অবশ্যই এটি করা উচিত। এটি "স্ট্রিং মাইস্ট্রিং" এর মতো - স্ট্রিংটি প্রকারটি ঘোষণা করছে। ইভেন্ট MyEventHandler TheEvent ঘোষণা দিচ্ছে যে এই ইভেন্টের সাথে ইন্টারঅ্যাক্ট করেছে তাকে অবশ্যই আমারEventHandler চুক্তি মেনে চলতে হবে। হ্যান্ডলার কনভেনশনটি কারণ চুক্তিটি মূলত ইভেন্টটিকে কীভাবে পরিচালনা করতে হয় তা বর্ণনা করে।
রেক্স এম

18
ঘটনাটি কীভাবে বরখাস্ত করা হয়?
আলকেমিক্যাল

17
@ রেক্স এম: "মাইএভেন্টহ্যান্ডলার" এর জন্য প্রথম সুস্পষ্ট ব্যাখ্যার জন্য আপনাকে ধন্যবাদ যে আমি কখনও দেখেছি :)
জোয়েল

10
এই পর্বের জন্য আপনাকে ধন্যবাদ: "ইভেন্ট এবং কার্যকর করার পদ্ধতিগুলির মধ্যে আঠালো প্রতিনিধিরা।", এটি সত্যিই দুর্দান্ত।
zionpi

103

সি # দুটি পদ জানে, delegateএবং event। প্রথমটি দিয়ে শুরু করা যাক।

প্রতিনিধি

delegateএকটি পদ্ধতির রেফারেন্স। আপনি যেমন একটি উদাহরণের জন্য একটি রেফারেন্স তৈরি করতে পারেন ঠিক তেমন:

MyClass instance = myFactory.GetInstance();

কোনও পদ্ধতির রেফারেন্স তৈরি করতে আপনি প্রতিনিধি ব্যবহার করতে পারেন:

Action myMethod = myFactory.GetInstance;

এখন আপনার কাছে কোনও পদ্ধতির এই রেফারেন্স রয়েছে, আপনি রেফারেন্সের মাধ্যমে পদ্ধতিটি কল করতে পারেন:

MyClass instance = myMethod();

তবে কেন করবে? আপনি কেবল myFactory.GetInstance()সরাসরি কল করতে পারেন । এই ক্ষেত্রে আপনি পারেন। তবে, আপনি অন্যান্য অ্যাপ্লিকেশনটির জ্ঞান থাকতে myFactoryবা কল করতে চান না এমন জায়গাগুলি ভাবার অনেকগুলি বিষয় রয়েছেmyFactory.GetInstance() সরাসরি ।

একটি সুস্পষ্ট এক যদি আপনি প্রতিস্থাপন পাবে চাই myFactory.GetInstance()মধ্যে myOfflineFakeFactory.GetInstance()একটি কেন্দ্রীয় জায়গা (ওরফে থেকে কারখানা পদ্ধতি প্যাটার্ন )।

কারখানার পদ্ধতি প্যাটার্ন

সুতরাং, যদি আপনার কোনও TheOtherClassক্লাস থাকে এবং এটির ব্যবহারের প্রয়োজন হয় তবে myFactory.GetInstance()এইভাবে কোডটি প্রতিনিধিদের ছাড়াই দেখতে হবে (আপনাকে আপনার TheOtherClassধরণের সম্পর্কে জানাতে হবে myFactory):

TheOtherClass toc;
//...
toc.SetFactory(myFactory);


class TheOtherClass
{
   public void SetFactory(MyFactory factory)
   {
      // set here
   }

}

আপনি যদি প্রতিনিধিদের ব্যবহার করতে চান তবে আমার কারখানার ধরণটি আপনাকে প্রকাশ করতে হবে না:

TheOtherClass toc;
//...
Action factoryMethod = myFactory.GetInstance;
toc.SetFactoryMethod(factoryMethod);


class TheOtherClass
{
   public void SetFactoryMethod(Action factoryMethod)
   {
      // set here
   }

}

সুতরাং, আপনি কোনও প্রকারের প্রতিনিধি তাদের প্রকারটি তাদের কাছে প্রকাশ না করেই ব্যবহার করতে পারেন। আপনি যে বিষয়টি প্রকাশ করছেন তা হ'ল আপনার পদ্ধতির স্বাক্ষর (আপনার কতগুলি পরামিতি রয়েছে এবং যেমন।)

"আমার পদ্ধতির স্বাক্ষর", এর আগে কোথায় শুনলাম? ও হ্যাঁ, ইন্টারফেস !!! ইন্টারফেস একটি সম্পূর্ণ শ্রেণীর স্বাক্ষর বর্ণনা করে। প্রতিনিধিদের কেবল একটি পদ্ধতির স্বাক্ষরের বর্ণনা হিসাবে চিন্তা করুন!

একটি ইন্টারফেস এবং একটি প্রতিনিধি মধ্যে অন্য একটি বড় পার্থক্য হ'ল আপনি যখন আপনার ক্লাসটি লিখছেন, তখন আপনাকে সি # "বলতে হবে না এই পদ্ধতিটি সেই ধরণের প্রতিনিধিকে প্রয়োগ করে"। ইন্টারফেসের সাথে, আপনাকে "এই শ্রেণিটি সেই ধরণের একটি ইন্টারফেস প্রয়োগ করে" বলতে হবে।

আরও, একটি প্রতিনিধি রেফারেন্স (কিছু সীমাবদ্ধতা সহ, নীচে দেখুন) একাধিক পদ্ধতি (ডাকা MulticastDelegate) উল্লেখ করতে পারে । এর অর্থ হ'ল আপনি যখন প্রতিনিধিকে কল করবেন তখন একাধিক সুস্পষ্টভাবে সংযুক্ত পদ্ধতি কার্যকর করা হবে। একটি অবজেক্ট রেফারেন্স সর্বদা কেবল একটি বস্তুর রেফারেন্স করতে পারে।

একটি জন্য বিধিনিষেধ MulticastDelegateযে (পদ্ধতি / প্রতিনিধি) স্বাক্ষর কোন রিটার্ন মান (থাকা উচিত নয় হয় void) এবং কীওয়ার্ড outএবং refস্বাক্ষর ব্যবহার করা হয় না। স্পষ্টতই, আপনি দুটি পদ্ধতি কল করতে পারবেন না যা একটি নম্বর ফেরত দেয় এবং একই নম্বরটি প্রত্যাবর্তনের আশা করে। স্বাক্ষরটি মেনে চললে প্রতিনিধি স্বয়ংক্রিয়ভাবে ক MulticastDelegate

ঘটনা

ইভেন্টগুলি হ'ল বৈশিষ্ট্য (যেমন; get; সেট; বৈশিষ্ট্যগুলিতে ক্ষেত্রগুলিতে) যা অন্যান্য বস্তু থেকে প্রতিনিধিটির সাবস্ক্রিপশন প্রকাশ করে। এই বৈশিষ্ট্যগুলি, তবে, সেটকে সমর্থন করে না; পরিবর্তে, তারা অ্যাড সমর্থন; অপসারণ;

সুতরাং আপনি থাকতে পারেন:

    Action myField;

    public event Action MyProperty
    {
        add { myField += value; }
        remove { myField -= value; }
    }

ইউআইতে ব্যবহার (উইনফোর্ডস, ডাব্লুপিএফ, ইউডাব্লুপি তাই)

সুতরাং, এখন আমরা জানি যে একটি প্রতিনিধি কোনও পদ্ধতির একটি রেফারেন্স এবং বিশ্বকে জানাতে আমাদের কোনও অনুষ্ঠান হতে পারে যে তারা আমাদের প্রতিনিধিদের কাছ থেকে রেফারেন্স করার জন্য তাদের পদ্ধতিগুলি আমাদের দিতে পারে, এবং আমরা একটি ইউআই বোতাম, তারপরে: আমরা আমাকে ক্লিক করা হয়েছে কিনা সে বিষয়ে আগ্রহী যে কেউ, তাদের সাথে আমাদের পদ্ধতিটি নিবন্ধিত করতে (আমাদের সামনে প্রকাশিত ইভেন্টের মাধ্যমে) জিজ্ঞাসা করতে পারে। আমাদের প্রদত্ত সেই সমস্ত পদ্ধতিগুলি আমরা ব্যবহার করতে পারি এবং আমাদের প্রতিনিধি দ্বারা সেগুলি উল্লেখ করতে পারি। এবং তারপরে, আমরা অপেক্ষা করব এবং অপেক্ষা করব .... যতক্ষণ না কোনও ব্যবহারকারী এসে সেই বোতামটিতে ক্লিক না করে, তারপরে আমাদের প্রতিনিধিটিকে আহ্বান করার যথেষ্ট কারণ থাকবে। এবং প্রতিনিধি আমাদের প্রদত্ত সেই সমস্ত পদ্ধতিগুলির উল্লেখ করে, সেই সমস্ত পদ্ধতিতে আমন্ত্রণ জানানো হবে। আমরা জানি না যে এই পদ্ধতিগুলি কী করে, বা আমরা জানি না কোন শ্রেণীটি সেগুলি প্রয়োগ করে। আমরা কেবল যত্ন করি তা হ'ল কেউ আমাদের ক্লিক করতে আগ্রহী ছিল,

জাভা

জাভার মতো ভাষায় প্রতিনিধি নেই have পরিবর্তে তারা ইন্টারফেস ব্যবহার করে। তারা যেভাবে তা করে তা হ'ল 'আমাদের ক্লিক করা হচ্ছে' এমন আগ্রহী যে কাউকে জিজ্ঞাসা করা, একটি নির্দিষ্ট ইন্টারফেস (একটি নির্দিষ্ট পদ্ধতি যা আমরা কল করতে পারি) প্রয়োগ করতে, তারপরে আমাদের পুরো উদাহরণটি দেয় যা ইন্টারফেসটি কার্যকর করে। আমরা এই ইন্টারফেসটি প্রয়োগকারী সমস্ত বস্তুর একটি তালিকা রাখি এবং যখনই আমরা ক্লিক করি তখন তাদের 'নির্দিষ্ট পদ্ধতিতে আমরা কল করতে পারি' কল করতে পারি।


ব্যাখ্যার জন্য চিয়ার্স কিন্তু গ্রাহকগণ গ্রহণকারী কোনও প্রতিনিধির উদাহরণ থেকে কীভাবে একটি ইভেন্ট আলাদা হয়? তারা উভয় একই জিনিস মত দেখতে?
বিকেএসপুরগাঁও

@BKSpurgeon যে কারণ তারা হয় "প্রতিনিধিদের যে গ্রাহক নিতে" - eventনিছক সিনট্যাক্স চিনি, কিছুই নয়।
ম্যাথিউ গুইনন

"একটি মাল্টিকাস্টডেলিগেটের জন্য বিধিনিষেধগুলি হ'ল (পদ্ধতি / প্রতিনিধি) স্বাক্ষরের কোনও রিটার্ন মান (শূন্য) হওয়া উচিত নয়", আমি মনে করি না এটি সঠিক। যদি তাদের ফেরতের মান থাকে তবে এটি সর্বশেষটি প্রদান করবে।
হোজিকিমারু

"এইভাবে, আপনি তাদের ধরণের কাছে তাদের প্রকার প্রকাশ না করেই অন্য কোনও শ্রেণীর প্রতিনিধি ব্যবহার করতে পারেন you're আপনি যে বিষয়টি প্রকাশ করছেন তা হ'ল আপনার পদ্ধতির স্বাক্ষর ..." - এটি আমার কাছে গুরুত্বপূর্ণ বিষয়। ধন্যবাদ!
রায়ান

40

এটি আসলে ইভেন্ট হ্যান্ডলারের জন্য ঘোষণা - এমন একটি পদ্ধতি যা কোনও ইভেন্ট নিক্ষেপ করা হলে ডাকা হবে। একটি ইভেন্ট তৈরি করতে, আপনি এই জাতীয় কিছু লিখতে চাই:

public class Foo
{
    public event EventHandler MyEvent;
}

এবং তারপরে আপনি ইভেন্টটির সাবস্ক্রাইব করতে পারেন:

Foo foo = new Foo();
foo.MyEvent += new EventHandler(this.OnMyEvent);

অনমাইভেন্ট () এর সাথে এটি সংজ্ঞায়িত করা হয়েছে:

private void OnMyEvent(object sender, EventArgs e)
{
    MessageBox.Show("MyEvent fired!");
}

যখনই Fooআগুন জ্বলবে MyEventতখন আপনার OnMyEventহ্যান্ডলারটি কল করা হবে।

আপনাকে সর্বদা EventArgsদ্বিতীয় প্যারামিটার হিসাবে উদাহরণ ব্যবহার করতে হবে না । আপনি যদি অতিরিক্ত তথ্য অন্তর্ভুক্ত করতে চান তবে আপনি প্রাপ্ত ক্লাস ব্যবহার করতে পারেন EventArgs( EventArgsএটি কনভেনশন অনুসারে বেস)। উদাহরণস্বরূপ, যদি আপনি Controlউইনফোর্মে বা ডাব্লুপিএফ- তে সংজ্ঞায়িত কিছু ইভেন্টের দিকে তাকান FrameworkElement, আপনি ইভেন্টের হ্যান্ডলারের কাছে অতিরিক্ত তথ্য দিয়ে যাওয়া ইভেন্টগুলির উদাহরণ দেখতে পারেন।


14
প্রশ্নের উত্তর দেওয়ার জন্য এবং প্রতিনিধি এবং ইভেন্টগুলিতে না যাওয়ার জন্য আপনাকে ধন্যবাদ।
split_byzero

3
আমি OnXXXআপনার ইভেন্ট হ্যান্ডলারের নামকরণের প্যাটার্নটি ব্যবহার করার বিরুদ্ধে সুপারিশ করব । (মূর্খতার সাথে, ওএনএক্সএক্সএক্সকে এমএফসি-তে 'হ্যান্ডেল এক্সএক্সএক্স' বোঝানো হয় এবং নেট থেকে 'এক্সএক্সএক্সএক্সএক্স' নেওয়া হয়, এবং এখন এর অর্থ অস্পষ্ট এবং বিভ্রান্তিকর - বিশদ বিবরণের জন্য এই পোস্টটি দেখুন )। পছন্দের নাম হবে RaiseXXXবাড়াতে ঘটনা, এবং HandleXXXবা Sender_XXXইভেন্ট হ্যান্ডলার জন্য।
জেসন উইলিয়ামস

1
আপনি কি একটি সাধারণ উইনফোর্ডস অ্যাপ্লিকেশন সহ একটি কাজের উদাহরণ প্রদর্শন করতে পারেন?
এমসি 9000

40

এখানে একটি কোড উদাহরণ যা সাহায্য করতে পারে:

using System;
using System.Collections.Generic;
using System.Text;

namespace Event_Example
{
  // First we have to define a delegate that acts as a signature for the
  // function that is ultimately called when the event is triggered.
  // You will notice that the second parameter is of MyEventArgs type.
  // This object will contain information about the triggered event.

  public delegate void MyEventHandler(object source, MyEventArgs e);

  // This is a class which describes the event to the class that receives it.
  // An EventArgs class must always derive from System.EventArgs.

  public class MyEventArgs : EventArgs
  {
    private string EventInfo;

    public MyEventArgs(string Text) {
      EventInfo = Text;
    }

    public string GetInfo() {
      return EventInfo;
    }
  }

  // This next class is the one which contains an event and triggers it
  // once an action is performed. For example, lets trigger this event
  // once a variable is incremented over a particular value. Notice the
  // event uses the MyEventHandler delegate to create a signature
  // for the called function.

  public class MyClass
  {
    public event MyEventHandler OnMaximum;

    private int i;
    private int Maximum = 10;

    public int MyValue
    {
      get { return i; }
      set
      {
        if(value <= Maximum) {
          i = value;
        }
        else 
        {
          // To make sure we only trigger the event if a handler is present
          // we check the event to make sure it's not null.
          if(OnMaximum != null) {
            OnMaximum(this, new MyEventArgs("You've entered " +
              value.ToString() +
              ", but the maximum is " +
              Maximum.ToString()));
          }
        }
      }
    }
  }

  class Program
  {
    // This is the actual method that will be assigned to the event handler
    // within the above class. This is where we perform an action once the
    // event has been triggered.

    static void MaximumReached(object source, MyEventArgs e) {
      Console.WriteLine(e.GetInfo());
    }

    static void Main(string[] args) {
      // Now lets test the event contained in the above class.
      MyClass MyObject = new MyClass();
      MyObject.OnMaximum += new MyEventHandler(MaximumReached);
      for(int x = 0; x <= 15; x++) {
        MyObject.MyValue = x;
      }
      Console.ReadLine();
    }
  }
}

4
ডেলিগেট OnMaximum?.Invoke(this,new MyEventArgs("you've entered..."));
প্রার্থনা

23

কেবল এখানে বিদ্যমান দুর্দান্ত উত্তরগুলি যুক্ত করতে - গৃহীত কোনওটিতে কোড তৈরি করা, যা একটি ব্যবহার করে delegate void MyEventHandler(string foo)...

কারণ সংকলকটি সামথিংহ্যাপড ইভেন্টের প্রতিনিধি প্রকারটি জানে , এটি:

myObj.SomethingHappened += HandleSomethingHappened;

সম্পূর্ণ সমতুল্য:

myObj.SomethingHappened += new MyEventHandler(HandleSomethingHappened);

এবং হ্যান্ডলারগুলিও এর সাথে নিবন্ধভুক্ত হতে পারে -=:

// -= removes the handler from the event's list of "listeners":
myObj.SomethingHappened -= HandleSomethingHappened;

সম্পূর্ণতার জন্য, ইভেন্ট উত্থাপনটি এইভাবে করা যেতে পারে, কেবল ইভেন্টটির মালিকানাধীন শ্রেণিতে:

//Firing the event is done by simply providing the arguments to the event:
var handler = SomethingHappened; // thread-local copy of the event
if (handler != null) // the event is null if there are no listeners!
{
    handler("Hi there!");
}

আমন্ত্রণটি থ্রেড-নিরাপদ কিনা তা নিশ্চিত করার জন্য হ্যান্ডলারের থ্রেড-স্থানীয় অনুলিপিটি প্রয়োজন - অন্যথায় কোনও থ্রেড গিয়ে ঘটনাটির শেষ হ্যান্ডলারটি নিবন্ধভুক্ত করতে পারে আমরা এটি ছিল কিনা তা যাচাই করার সাথে সাথেই null, এবং NullReferenceExceptionসেখানে আমাদের একটি "মজা" হবে would ।


সি # 6 এই নিদর্শনটির জন্য একটি দুর্দান্ত সংক্ষিপ্ত হাত উপস্থাপন করেছে। এটি নাল প্রচারের অপারেটর ব্যবহার করে।

SomethingHappened?.Invoke("Hi there!");

13

ঘটনাগুলি সম্পর্কে আমার বোঝাপড়াটি;

প্রতিনিধি নিয়োগ করুন:

কার্যকর করার জন্য পদ্ধতি / পদ্ধতির রেফারেন্স ধরে রাখার জন্য একটি পরিবর্তনশীল। এটি ভেরিয়েবলের মতো পদ্ধতিগুলির চারপাশে পাস করা সম্ভব করে তোলে।

ইভেন্টটি তৈরি এবং কল করার পদক্ষেপ:

  1. ইভেন্টটি একটি প্রতিনিধি একটি উদাহরণ

  2. যেহেতু কোনও ইভেন্ট প্রতিনিধিদের উদাহরণ, সুতরাং আমাদের প্রথমে প্রতিনিধিটিকে সংজ্ঞায়িত করতে হবে।

  3. ইভেন্টটি চালিত হওয়ার পরে কার্যকর করার পদ্ধতি / পদ্ধতিগুলি নির্ধারণ করুন ( প্রতিনিধিকে ফোন করা )

  4. ইভেন্টটি ফায়ার করুন ( প্রতিনিধিকে কল করুন )

উদাহরণ:

using System;

namespace test{
    class MyTestApp{
        //The Event Handler declaration
        public delegate void EventHandler();

        //The Event declaration
        public event EventHandler MyHandler;

        //The method to call
        public void Hello(){
            Console.WriteLine("Hello World of events!");
        }

        public static void Main(){
            MyTestApp TestApp = new MyTestApp();

            //Assign the method to be called when the event is fired
            TestApp.MyHandler = new EventHandler(TestApp.Hello);

            //Firing the event
            if (TestApp.MyHandler != null){
                TestApp.MyHandler();
            }
        }

    }   

}

3

প্রকাশক: যেখানে ঘটনা ঘটে। কোন শ্রেণীর প্রতিনিধি শ্রেণি ব্যবহার করছে তা প্রকাশকের নির্দিষ্ট করে প্রয়োজনীয় আর্গুমেন্ট তৈরি করা উচিত, সেই যুক্তিগুলি পাস করুন এবং নিজেই প্রতিনিধিটির কাছে প্রেরণ করুন।

গ্রাহক: যেখানে প্রতিক্রিয়া ঘটে। গ্রাহকরা ইভেন্টগুলির প্রতিক্রিয়া জানানোর জন্য পদ্ধতিগুলি নির্দিষ্ট করতে হবে। এই পদ্ধতিগুলিতে প্রতিনিধি হিসাবে একই ধরণের আর্গুমেন্ট নেওয়া উচিত। গ্রাহকরা এই পদ্ধতিটি প্রকাশকের প্রতিনিধিতে যুক্ত করুন।

সুতরাং, যখন ইভেন্টটি প্রকাশকের মধ্যে ঘটে তখন প্রতিনিধিরা কিছু ইভেন্ট আর্গুমেন্ট (ডেটা ইত্যাদি) পাবেন তবে এই সমস্ত ডেটা দিয়ে কী হবে তা প্রকাশকের কোনও ধারণা নেই। গ্রাহকগণ প্রকাশকের শ্রেণীর ইভেন্টগুলিতে প্রতিক্রিয়া জানাতে তাদের নিজস্ব শ্রেণিতে পদ্ধতি তৈরি করতে পারেন, যাতে গ্রাহকরা প্রকাশকের ইভেন্টগুলিতে প্রতিক্রিয়া জানাতে পারেন।


2
//This delegate can be used to point to methods
//which return void and take a string.
public delegate void MyDelegate(string foo);

//This event can cause any method which conforms
//to MyEventHandler to be called.
public event MyDelegate MyEvent;

//Here is some code I want to be executed
//when SomethingHappened fires.
void MyEventHandler(string foo)
{
    //Do some stuff
}

//I am creating a delegate (pointer) to HandleSomethingHappened
//and adding it to SomethingHappened's list of "Event Handlers".
myObj.MyEvent += new MyDelegate (MyEventHandler);

0

আমি ইভেন্টের কীওয়ার্ডটিকে 'অ্যাকশন কোলাকশন' এর একটি উপাধ হিসাবে দেখি কারণ ইভেন্টটি সম্পাদনের জন্য ক্রিয়াকলাপের (যেমন ডেলিগ্রেট) ধারণ করে তাই আমি কেই 50 এর সাথে একমত হই।

using System;

namespace test{

class MyTestApp{
    //The Event Handler declaration
    public delegate void EventAction();

    //The Event Action Collection 
    //Equivalent to 
    //  public List<EventAction> EventActions=new List<EventAction>();
    //        
    public event EventAction EventActions;

    //An Action
    public void Hello(){
        Console.WriteLine("Hello World of events!");
    }
    //Another Action
    public void Goodbye(){
        Console.WriteLine("Goodbye Cruel World of events!");
    }

    public static void Main(){
        MyTestApp TestApp = new MyTestApp();

        //Add actions to the collection
        TestApp.EventActions += TestApp.Hello;
        TestApp.EventActions += TestApp.Goodbye;

        //Invoke all event actions
        if (TestApp.EventActions!= null){
            //this peculiar syntax hides the invoke 
            TestApp.EventActions();
            //using the 'ActionCollection' idea:
            // foreach(EventAction action in TestApp.EventActions)
            //     action.Invoke();
        }
    }

}   

}

0

পোস্টে দুর্দান্ত প্রযুক্তিগত উত্তর! এটিকে যুক্ত করার মতো প্রযুক্তিগতভাবে আমার কাছে কিছুই নেই ।

সাধারণভাবে ভাষা ও সফ্টওয়্যারগুলিতে নতুন বৈশিষ্ট্য উপস্থিত হওয়ার প্রধান কারণ হ'ল বিপণন বা সংস্থার রাজনীতি! :-) এটি অবশ্যই অনুমানের অধীনে হবে না!

আমি মনে করি এটি প্রতিনিধিদের এবং ইভেন্টগুলিতেও নির্দিষ্ট কিছু ক্ষেত্রে প্রযোজ্য! আমি তাদের দরকারী বলে মনে করি এবং সি # ভাষায় মান যুক্ত করি, তবে অন্যদিকে জাভা ভাষা সেগুলি ব্যবহার না করার সিদ্ধান্ত নিয়েছে! তারা সিদ্ধান্ত নিয়েছে যে আপনি প্রতিনিধিদের সাথে যা কিছু সমাধান করছেন আপনি ইতিমধ্যে ভাষার বিদ্যমান বৈশিষ্ট্যগুলি যেমন ইন্টারফেসগুলি যেমন সমাধান করতে পারেন

এখন 2001 এর কাছাকাছি মাইক্রোসফ্ট জাভা প্রতিযোগী সমাধান হিসাবে .NET ফ্রেমওয়ার্ক এবং সি # ভাষা প্রকাশ করেছে, তাই জাভা নেই এমন নতুন বৈশিষ্ট্যগুলি রাখা ভাল ছিল।


0

আমি সম্প্রতি # # তে ইভেন্টগুলি কীভাবে ব্যবহার করতে পারি তার একটি উদাহরণ তৈরি করেছি এবং এটি আমার ব্লগে পোস্ট করেছি। আমি খুব সহজ উদাহরণ সহ এটি যতটা সম্ভব স্পষ্ট করার চেষ্টা করেছি। এটি যদি কারও সাহায্য করতে পারে তবে তা এখানে: http://www.konsfik.com/using-events-in-csharp/

এটিতে বিবরণ এবং উত্স কোড (প্রচুর মন্তব্য সহ) অন্তর্ভুক্ত রয়েছে এবং এটি মূলত ইভেন্ট এবং ইভেন্ট হ্যান্ডলারের একটি যথাযথ (টেম্পলেট - মত) ব্যবহারের উপর দৃষ্টি নিবদ্ধ করে।

কয়েকটি মূল বিষয় হ'ল:

  • ইভেন্টগুলি "উপ-প্রকারের প্রতিনিধিদের" মতো, কেবল আরও সীমাবদ্ধ (ভাল উপায়ে)। আসলে কোনও ইভেন্টের ঘোষণায় সর্বদা একটি প্রতিনিধি অন্তর্ভুক্ত থাকে (ইভেন্টহ্যান্ডাররা একধরণের প্রতিনিধি)।

  • ইভেন্ট হ্যান্ডলারগুলি নির্দিষ্ট ধরণের প্রতিনিধি (আপনি এগুলি একটি টেম্পলেট হিসাবে ভাবতে পারেন), যা ব্যবহারকারীদের একটি নির্দিষ্ট "স্বাক্ষর" রয়েছে এমন ইভেন্টগুলি তৈরি করতে বাধ্য করে। স্বাক্ষরটি বিন্যাসটির: (অবজেক্ট প্রেরক, ইভেন্টআর্গ ইভেন্ট ইভেন্টস)।

  • ইভেন্টটি জানাতে যে কোনও ধরণের তথ্য অন্তর্ভুক্ত করতে আপনি ইভেন্টআর্গের নিজস্ব উপ-শ্রেণি তৈরি করতে পারেন। ইভেন্টগুলি ব্যবহার করার সময় ইভেন্টহ্যান্ডলারগুলি ব্যবহার করার দরকার নেই। আপনি এগুলিকে পুরোপুরি এড়িয়ে যেতে পারেন এবং তাদের জায়গায় নিজের ধরণের প্রতিনিধি ব্যবহার করতে পারেন।

  • ইভেন্ট এবং প্রতিনিধিদের ব্যবহারের মধ্যে একটি মূল পার্থক্য হ'ল ঘটনাগুলি কেবল শ্রেণীর মধ্যেই ঘোষণা করা যেতে পারে যা তাদের ঘোষিত হয়েছিল, যদিও সেগুলি জনসাধারণ হিসাবে ঘোষণা করা হয়েছিল। এটি একটি অত্যন্ত গুরুত্বপূর্ণ পার্থক্য, কারণ এটি আপনার ইভেন্টগুলিকে উন্মুক্ত করতে দেয় যাতে তারা বাহ্যিক পদ্ধতির সাথে "সংযুক্ত" থাকে, একই সময়ে তারা "বাহ্যিক অপব্যবহার" থেকে সুরক্ষিত থাকে।


0

আরেকটি বিষয় সম্পর্কে জানতে হবে , কিছু ক্ষেত্রে আপনার যখন কম স্তরের সংযোগের প্রয়োজন হয় তখন আপনাকে প্রতিনিধি / ইভেন্টগুলি ব্যবহার করতে হয় !

আপনি যদি অ্যাপ্লিকেশনটিতে কোনও স্থানে কোনও উপাদান ব্যবহার করতে চান , আপনার নিম্ন স্তরের সংযোগের একটি উপাদান তৈরি করতে হবে এবং নির্দিষ্ট উদ্বেগহীন লোগিককে অবশ্যই আপনার উপাদানটির বহির্ভূত দায়িত্ব অর্পণ করতে হবে ! এটি নিশ্চিত করে যে আপনার একটি ডিকোপল্ড সিস্টেম এবং একটি ক্লিনার কোড রয়েছে।

ইন কঠিন নীতি এই "হয় ডি ", ( ডি ependency বিপর্যয় নীতি)।

" আইওসি " নামে পরিচিত , নিয়ন্ত্রণের বিপরীতমুখী

আপনি ইভেন্ট, প্রতিনিধি এবং ডিআই (নির্ভরতা ইনজেকশন) দিয়ে " আইওসি " তৈরি করতে পারেন ।

শিশু শ্রেণিতে কোনও পদ্ধতি অ্যাক্সেস করা সহজ। তবে সন্তানের কাছ থেকে পিতামাতাদের ক্লাসে কোনও পদ্ধতি অ্যাক্সেস করা আরও কঠিন। আপনাকে সন্তানের কাছে পিতামাতার রেফারেন্সটি পাস করতে হবে! (বা ইন্টারফেসের সাথে ডিআই ব্যবহার করুন)

প্রতিনিধি / ইভেন্টগুলি আমাদের সন্তানের কাছ থেকে রেফারেন্স ছাড়াই পিতামাতার কাছে যোগাযোগ করতে দেয়!

এখানে চিত্র বর্ণনা লিখুন

উপরের এই চিত্রটিতে আমি ডেলিগেট / ইভেন্ট ব্যবহার করি না এবং এ-এর পদ্ধতিতে উদ্বেগহীন ব্যবসায়িক যুক্তি সম্পাদন করতে প্যারেন্ট উপাদান A এর একটি রেফারেন্স থাকতে হবে (উচ্চ স্তরের মিলন)

এই পদ্ধতির সাথে, আমি সমস্ত উপাদান যা বি উপাদান ব্যবহার করে সমস্ত রেফারেন্স রাখতে হবে! :(

এখানে চিত্র বর্ণনা লিখুন

উপরের এই চিত্রটিতে, আমি ডেলিগেট / ইভেন্ট ব্যবহার করি এবং বি উপাদানটি B এর সাথে পরিচিত হতে হবে না (সংযোগের নিম্ন স্তরের)

এবং আপনি আপনার অ্যাপ্লিকেশনের যে কোনও জায়গায় আপনার উপাদান বি ব্যবহার করতে পারেন !

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.