প্রতিনিধি এবং একটি ইভেন্টের মধ্যে পার্থক্য কী? উভয়ই কার্যকর করা যেতে পারে এমন ফাংশনগুলির রেফারেন্স রাখে না?
প্রতিনিধি এবং একটি ইভেন্টের মধ্যে পার্থক্য কী? উভয়ই কার্যকর করা যেতে পারে এমন ফাংশনগুলির রেফারেন্স রাখে না?
উত্তর:
একটি ইভেন্ট ঘোষণা বিমূর্ততা এবং এর সুরক্ষা একটি মাত্রা জোড়ে প্রতিনিধি উদাহরণস্বরূপ। এই সুরক্ষা প্রতিনিধি ক্লায়েন্টদের ডেলিগেট এবং এর আহ্বান তালিকার পুনরায় সেট করতে বাধা দেয় এবং কেবলমাত্র অনুরোধ তালিকা থেকে লক্ষ্যগুলি যুক্ত বা অপসারণের অনুমতি দেয়।
পার্থক্যগুলি বুঝতে আপনি এই 2 টি উদাহরণটি দেখতে পারেন
প্রতিনিধিদের সাথে উদাহরণ (এই ক্ষেত্রে, একটি অ্যাকশন - এটি এমন একধরণের প্রতিনিধি যা কোনও মূল্য ফেরায় না)
public class Animal
{
public Action Run {get; set;}
public void RaiseEvent()
{
if (Run != null)
{
Run();
}
}
}
প্রতিনিধি ব্যবহার করতে, আপনার এই জাতীয় কিছু করা উচিত:
Animal animal= new Animal();
animal.Run += () => Console.WriteLine("I'm running");
animal.Run += () => Console.WriteLine("I'm still running") ;
animal.RaiseEvent();
এই কোডটি ভাল কাজ করে তবে আপনার কিছু দুর্বল দাগ থাকতে পারে।
উদাহরণস্বরূপ, আমি যদি এটি লিখি:
animal.Run += () => Console.WriteLine("I'm running");
animal.Run += () => Console.WriteLine("I'm still running");
animal.Run = () => Console.WriteLine("I'm sleeping") ;
কোডের শেষ লাইনের সাথে আমি পূর্বের আচরণগুলি কেবল একটি অনুপস্থিতের সাথে ওভাররাইড +
করেছি ( =
পরিবর্তে আমি ব্যবহার করেছি +=
)
আর একটি দুর্বল স্পট হ'ল আপনার Animal
ক্লাসটি ব্যবহার করে এমন প্রতিটি শ্রেণি RaiseEvent
কেবল এটি কল করতে পারে animal.RaiseEvent()
।
এই দুর্বল দাগগুলি এড়াতে events
আপনি সি # তে ব্যবহার করতে পারেন ।
আপনার প্রাণী শ্রেণিটি এভাবে পরিবর্তিত হবে:
public class ArgsSpecial : EventArgs
{
public ArgsSpecial (string val)
{
Operation=val;
}
public string Operation {get; set;}
}
public class Animal
{
// Empty delegate. In this way you are sure that value is always != null
// because no one outside of the class can change it.
public event EventHandler<ArgsSpecial> Run = delegate{}
public void RaiseEvent()
{
Run(this, new ArgsSpecial("Run faster"));
}
}
ইভেন্ট কল করতে
Animal animal= new Animal();
animal.Run += (sender, e) => Console.WriteLine("I'm running. My value is {0}", e.Operation);
animal.RaiseEvent();
পার্থক্য:
মন্তব্য:
ইভেন্টহ্যান্ডলারকে নিম্নলিখিত প্রতিনিধি হিসাবে ঘোষণা করা হয়েছে:
public delegate void EventHandler (object sender, EventArgs e)
এটি একটি প্রেরক (অবজেক্ট টাইপের) এবং ইভেন্টের আর্গুমেন্টগুলি লাগে। প্রেরক যদি স্থির পদ্ধতি থেকে আসে তবে তা বাতিল হয়।
এই উদাহরণ, যা ব্যবহার করে EventHandler<ArgsSpecial>
, EventHandler
পরিবর্তে ব্যবহার করেও লেখা যেতে পারে be
পড়ুন এখানে EventHandler সম্পর্কে নথিপত্রের জন্য
RaiseEvent
কলিং পদ্ধতির animal
ইভেন্ট ব্যবহার করা কোডটিতে এমন কোনও উদাহরণের অ্যাক্সেস রয়েছে ততক্ষণ কেউ কল করতে পারবেন না ?
animal.Run(this, new ArgsSpecial("Run faster");
?
সিনথেটিক এবং অপারেশনাল বৈশিষ্ট্যগুলি ছাড়াও একটি শব্দার্থক পার্থক্য রয়েছে।
প্রতিনিধিরা, ধারণামূলকভাবে, ফাংশন টেম্পলেটগুলি; অর্থাৎ, তারা একটি চুক্তি প্রকাশ করে একটি প্রতিনিধিদলের "প্রকার" বিবেচনা করার জন্য একটি ফাংশন অবশ্যই মেনে চলতে হবে।
ইভেন্টগুলি প্রতিনিধিত্ব করে ... ভাল, ইভেন্টগুলি। তারা যখন কিছু ঘটে তখন কাউকে সতর্ক করার উদ্দেশ্যে এবং হ্যাঁ, তারা একটি প্রতিনিধি সংজ্ঞা মেনে চলে তবে তারা একই জিনিস নয়।
এমনকি যদি তারা ঠিক একই জিনিস ছিল (সিনট্যাক্টিকালি এবং আইএল কোডে) তখনও শব্দার্থগত পার্থক্য থাকবে। সাধারণভাবে আমি দুটি ভিন্ন ধারণার জন্য দুটি আলাদা নাম রাখতে পছন্দ করি, এমনকি যদি সেগুলি একইভাবে প্রয়োগ করা হয় (তবে এর অর্থ এই নয় যে আমি একই কোডটি দুটিবারই পেতে চাই)।
এখানে উল্লেখ করার জন্য আরও একটি ভাল লিঙ্ক। http://csharpindepth.com/Articles/Chapter2/Events.aspx
সংক্ষেপে, নিবন্ধটি থেকে দূরে সরে যান - ইভেন্টগুলি প্রতিনিধিদের উপর encapsulation হয়।
নিবন্ধ থেকে উদ্ধৃতি:
ধরুন ঘটনা # সি / / নেট তে একটি ধারণা হিসাবে উপস্থিত ছিল না। অন্য শ্রেণি কীভাবে কোনও ইভেন্টের সদস্যতা নেবে? তিনটি বিকল্প:
একটি পাবলিক প্রতিনিধি পরিবর্তনশীল
একটি সম্পত্তি দ্বারা সমর্থিত একটি প্রতিনিধি পরিবর্তনশীল
অ্যাডএক্সএক্সএক্সএন্ডহ্যান্ডলার এবং রিমুভ এক্সএক্সএক্সএইচএন্ডহ্যান্ডলার পদ্ধতি সহ একটি প্রতিনিধি পরিবর্তনশীল able
বিকল্প 1 স্পষ্টতই ভয়ঙ্কর, সমস্ত সাধারণ কারণে আমরা পাবলিক ভেরিয়েবলকে ঘৃণা করি।
বিকল্প 2 সামান্য ভাল, তবে গ্রাহকদের কার্যকরভাবে একে অপরকে ওভাররাইড করার অনুমতি দেয় - এটি কিছুটা লিখতে খুব সহজ হবে IIstance.MyEvent = ইভেন্টহ্যান্ডলার; যা কোনও নতুন ইভেন্ট যুক্ত করার পরিবর্তে কোনও বিদ্যমান ইভেন্ট হ্যান্ডলারকে প্রতিস্থাপন করবে। উপরন্তু, আপনি এখনও বৈশিষ্ট্য লিখতে হবে।
অপশন 3 মূলত ইভেন্টগুলি আপনাকে যা দেয় তা হ'ল তবে গ্যারান্টিযুক্ত কনভেনশন সহ (সংকলক দ্বারা উত্পাদিত এবং আইএল-এ অতিরিক্ত পতাকা দ্বারা সমর্থিত) এবং ক্ষেত্রের মতো ইভেন্টগুলি আপনাকে যে শব্দার্থকতা দেয় সে সম্পর্কে আপনি যদি খুশি হন তবে একটি "ফ্রি" বাস্তবায়ন। ইভেন্ট হ্যান্ডলারের তালিকায় যথেচ্ছ অ্যাক্সেসের অনুমতি না দিয়ে ইভেন্টগুলিতে সাবস্ক্রাইব এবং সদস্যতা ছাড়াই এনক্যাপসুলেটেড হয় এবং ভাষা ঘোষণা এবং সাবস্ক্রিপশন উভয়ের জন্য সিনট্যাক্স সরবরাহ করে বিষয়গুলিকে আরও সহজ করে তুলতে পারে।
public Delegate
পরিবর্তনশীল "ডেটা" প্রকাশ করবে তবে আমার জ্ঞানের সর্বোত্তম হিসাবে ওওপি কখনও কখনও কোনও ধারণার মতো নয় Delegate
(এটি কোনও "অবজেক্ট" বা "বার্তা" নয়) , এবং। নেট সত্যিই সবেমাত্র ডেটার মতো প্রতিনিধিদের সাথে আচরণ করে।
AddXXXHandler
একটি private Delegate
ভেরিয়েবলের সাহায্যে আপনার নিজস্ব পদ্ধতি তৈরি করা ভাল বিকল্প হতে পারে। এই ক্ষেত্রে আপনি কোনও হ্যান্ডলার ইতিমধ্যে সেট করা আছে কিনা তা পরীক্ষা করে দেখতে পারেন এবং যথাযথ প্রতিক্রিয়া জানান। আপনার যদি Delegate
হ্যান্ডেলটি ধারণ করে রাখা সমস্ত বস্তু সমস্ত হ্যান্ডলারগুলি সাফ করতে সক্ষম হয় ( event
এটি করার কোনও উপায় আপনাকে দেয় না) তবে এটি একটি ভাল সেটআপও হতে পারে ।
দ্রষ্টব্য: যদি আপনার সি # 5.0 প্রকাশিত অ্যাক্সেস থাকে তবে দু'জনের মধ্যে পার্থক্যটি আরও ভালভাবে বুঝতে "অধ্যায়গুলি" শিরোনামের 18 অধ্যায়ে "প্রতিনিধিদের সাধারণ ব্যবহারের সীমাবদ্ধতা" পড়ুন।
এটি সর্বদা আমাকে একটি সহজ, সুনির্দিষ্ট উদাহরণ রাখতে সহায়তা করে। সুতরাং এখানে সম্প্রদায়ের জন্য একটি। প্রথমে আমি দেখায় আপনি কীভাবে প্রতিনিধিদের ব্যবহার করতে পারেন ইভেন্টগুলি আমাদের জন্য যা করতে তা করতে। তারপরে আমি দেখাব কীভাবে একই সমাধানটি উদাহরণের সাথে কাজ করবে EventHandler
। এবং তারপরে আমি ব্যাখ্যা করি যে আমি প্রথম উদাহরণে যা ব্যাখ্যা করি তা আমরা কেন করতে চাই না। এই পোস্টটি জন স্কিটির একটি নিবন্ধ দ্বারা অনুপ্রাণিত হয়েছিল ।
উদাহরণ 1: জন প্রতিনিধি ব্যবহার করে
ধরুন আমার কাছে একটি ড্রপ-ডাউন বক্স সহ একটি উইনফর্মস অ্যাপ রয়েছে। ড্রপ ডাউন একটি আবদ্ধ List<Person>
। যেখানে ব্যক্তির আইডি, নাম, ডাকনাম, চুলের রঙের বৈশিষ্ট্য রয়েছে। মূল ফর্মটিতে একটি কাস্টম ব্যবহারকারী নিয়ন্ত্রণ যা সেই ব্যক্তির বৈশিষ্ট্যগুলি দেখায়। যখন কেউ কোনও ব্যক্তিকে নির্বাচিত ব্যক্তির বৈশিষ্ট্যগুলি দেখানোর জন্য ব্যবহারকারী নিয়ন্ত্রণ আপডেটের ড্রপ-ডাউন লেবেলে নির্বাচন করে।
এখানে যে কিভাবে কাজ করে। আমাদের তিনটি ফাইল রয়েছে যা আমাদের এটি একসাথে রাখতে সহায়তা করে:
এখানে প্রতিটি ক্লাসের জন্য সম্পর্কিত কোড রয়েছে:
class Mediator
{
public delegate void PersonChangedDelegate(Person p); //delegate type definition
public static PersonChangedDelegate PersonChangedDel; //delegate instance. Detail view will "subscribe" to this.
public static void OnPersonChanged(Person p) //Form1 will call this when the drop-down changes.
{
if (PersonChangedDel != null)
{
PersonChangedDel(p);
}
}
}
এখানে আমাদের ব্যবহারকারীর নিয়ন্ত্রণ:
public partial class DetailView : UserControl
{
public DetailView()
{
InitializeComponent();
Mediator.PersonChangedDel += DetailView_PersonChanged;
}
void DetailView_PersonChanged(Person p)
{
BindData(p);
}
public void BindData(Person p)
{
lblPersonHairColor.Text = p.HairColor;
lblPersonId.Text = p.IdPerson.ToString();
lblPersonName.Text = p.Name;
lblPersonNickName.Text = p.NickName;
}
}
অবশেষে আমাদের ফর্ম 1 সিএসে নিম্নলিখিত কোড রয়েছে। এখানে আমরা কল করছি অনপারসন চ্যাঞ্জড, যা ডেলিগেটের সদস্যতাযুক্ত কোনও কোডকে কল করে।
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
Mediator.OnPersonChanged((Person)comboBox1.SelectedItem); //Call the mediator's OnPersonChanged method. This will in turn call all the methods assigned (i.e. subscribed to) to the delegate -- in this case `DetailView_PersonChanged`.
}
ঠিক আছে. সুতরাং আপনি কীভাবে ইভেন্টগুলি ব্যবহার না করে এবং কেবলমাত্র প্রতিনিধি ব্যবহার না করেই এই কাজটি পাবেন । আমরা কেবলমাত্র একটি সার্বজনীন প্রতিনিধিকে একটি শ্রেণিতে রেখেছি - আপনি এটি স্ট্যাটিক বা সিঙ্গলটন, বা যা কিছু করতে পারেন। গ্রেট।
বাট, বাট, কিন্তু, আমি কেবল উপরে বর্ণিত যা করতে চাই না। কারণ সরকারী ক্ষেত্রগুলি অনেকের পক্ষে খারাপ , অনেক কারণে। তাহলে আমাদের বিকল্পগুলি কি? জন স্কিট যেমন বর্ণনা করেছেন, এখানে আমাদের বিকল্পগুলি রয়েছে:
PersonChangedDel = null
অন্য সমস্ত সাবস্ক্রিপশন মুছে ফেলাতে বলতে পারি The এখানে অন্য সমস্যাটি রয়ে গেছে যেহেতু ব্যবহারকারীদের ডেলিগেটের অ্যাক্সেস রয়েছে তাই তারা অনুরোধের তালিকায় লক্ষ্যগুলি ডেকে আনতে পারে - আমরা কখনই আমাদের ইভেন্টগুলি বাড়ানোর জন্য বহিরাগত ব্যবহারকারীদের অ্যাক্সেস থাকতে চাই না।এই তৃতীয় বিকল্পটি মূলত কোনও ইভেন্ট আমাদের দেয়। যখন আমরা কোনও ইভেন্টহ্যান্ডলার ঘোষণা করি, এটি আমাদেরকে প্রতিনিধিদের অ্যাক্সেস দেয় - প্রকাশ্যে নয়, সম্পত্তি হিসাবে নয়, এই জিনিস হিসাবে আমরা এমন একটি ইভেন্ট বলি যা সবেমাত্র অ্যাক্সেসর যুক্ত / সরিয়ে দিয়েছে।
আসুন দেখুন একই প্রোগ্রামটি দেখতে কেমন, তবে এখন জন প্রতিনিধিদের পরিবর্তে একটি ইভেন্ট ব্যবহার করছি (আমি আমাদের মধ্যস্থতাকে একটি সিঙ্গলটনেও পরিবর্তন করেছি):
উদাহরণ 2: জন প্রতিনিধি পরিবর্তে ইভেন্ট হ্যান্ডলার সহ H
মধ্যস্থ:
class Mediator
{
private static readonly Mediator _Instance = new Mediator();
private Mediator() { }
public static Mediator GetInstance()
{
return _Instance;
}
public event EventHandler<PersonChangedEventArgs> PersonChanged; //this is just a property we expose to add items to the delegate.
public void OnPersonChanged(object sender, Person p)
{
var personChangedDelegate = PersonChanged as EventHandler<PersonChangedEventArgs>;
if (personChangedDelegate != null)
{
personChangedDelegate(sender, new PersonChangedEventArgs() { Person = p });
}
}
}
লক্ষ্য করুন যে আপনি ইভেন্টহ্যান্ডলার এফ 12 করে দিলে এটি আপনাকে সংজ্ঞাটি দেখাবে যে অতিরিক্ত "প্রেরক" অবজেক্টের সাথে জেনেরিক-আইফিড প্রতিনিধি:
public delegate void EventHandler<TEventArgs>(object sender, TEventArgs e);
ব্যবহারকারী নিয়ন্ত্রণ:
public partial class DetailView : UserControl
{
public DetailView()
{
InitializeComponent();
Mediator.GetInstance().PersonChanged += DetailView_PersonChanged;
}
void DetailView_PersonChanged(object sender, PersonChangedEventArgs e)
{
BindData(e.Person);
}
public void BindData(Person p)
{
lblPersonHairColor.Text = p.HairColor;
lblPersonId.Text = p.IdPerson.ToString();
lblPersonName.Text = p.Name;
lblPersonNickName.Text = p.NickName;
}
}
অবশেষে, এখানে ফর্ম 1 কোড কোড রয়েছে:
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
Mediator.GetInstance().OnPersonChanged(this, (Person)comboBox1.SelectedItem);
}
যেহেতু ইভেন্টহ্যান্ডলার প্যারামিটার হিসাবে চায় এবং ইভেন্টআর্গস, তাই আমি এই ক্লাসটিতে কেবল একটি একক সম্পত্তি রেখে তৈরি করেছি:
class PersonChangedEventArgs
{
public Person Person { get; set; }
}
আশা করি যে এটি আমাদের কেন অনুষ্ঠানগুলি করে এবং সেগুলি কীভাবে আলাদা সেগুলি সম্পর্কে কিছুটা দেখায় - তবে কার্যত একইভাবে - প্রতিনিধি হিসাবে।
The other problem that remains here is that since the users have access to the delegate, they can invoke the targets in the invocation list -- we don't want external users having access to when to raise our events
। এর সর্বশেষতম সংস্করণে Mediator
, আপনি OnPersonChange
যখনই সিঙ্গলটনের রেফারেন্স পাবেন তখনও আপনি কল করতে পারবেন । হতে পারে আপনার উল্লেখ করা উচিত যে Mediator
পদ্ধতির সেই নির্দিষ্ট আচরণটি প্রতিরোধ করা হয় না, এবং ইভেন্ট বাসের কাছাকাছি।
আপনি ইন্টারফেসের ঘোষণায় ইভেন্টগুলিও ব্যবহার করতে পারেন, প্রতিনিধিদের জন্য নয় so
Action a { get; set; }
একটি ইন্টারফেস সংজ্ঞা ভিতরে থাকতে পারে ।
ইভেন্ট এবং প্রতিনিধিদের মধ্যে কি দুর্দান্ত ভুল বোঝাবুঝি !!! একটি প্রতিনিধি একটি টিওয়াইপি (যেমন একটি class
, বা একটি কর interface
) নির্দিষ্ট করে, অন্যদিকে ইভেন্টটি কেবল এক ধরণের সদস্য (যেমন ক্ষেত্র, বৈশিষ্ট্য ইত্যাদি)। এবং অন্যান্য সদস্যের মতোই কোনও ইভেন্টেরও একটি প্রকার থাকে। তবুও, কোনও ইভেন্টের ক্ষেত্রে, অনুষ্ঠানের ধরণটি অবশ্যই কোনও প্রতিনিধি দ্বারা নির্দিষ্ট করা আবশ্যক। উদাহরণস্বরূপ, আপনি কোনও ইন্টারফেস দ্বারা সংজ্ঞায়িত কোনও ধরণের ইভেন্ট ঘোষণা করতে পারবেন না।
সমাপ্তি, আমরা নিম্নলিখিত পর্যবেক্ষণ করতে পারি : একটি প্রতিনিধি দ্বারা সংঘবদ্ধ হওয়া আবশ্যক ইভেন্টের ধরণ । এটা এমন এক ঘটনা এবং একটি প্রতিনিধি মধ্যে মূল সম্পর্ক নেই এবং বিভাগে বর্ণনা করা হয়েছে II.18 সংজ্ঞা ঘটনা এর ECMA-335 (CLI) দ্বারা পার্টিশন আমি ষষ্ঠ থেকে :
সাধারণ ব্যবহারে, টাইপস্পেক (যদি উপস্থিত থাকে) এমন কোনও প্রতিনিধি সনাক্ত করে যার স্বাক্ষরটি ঘটনার আগুন পদ্ধতিতে আর্গুমেন্টের সাথে মেলে।
তবে, এই ঘটনাটি বোঝায় না যে কোনও ইভেন্ট একটি ব্যাকিং প্রতিনিধি ক্ষেত্র ব্যবহার করে । সত্য সত্য, কোনও ইভেন্ট আপনার পছন্দের কোনও পৃথক ডেটা স্ট্রাকচার ধরণের ব্যাকিং ফিল্ড ব্যবহার করতে পারে। আপনি যদি সি # তে স্পষ্টভাবে কোনও ইভেন্ট বাস্তবায়ন করেন, আপনি ইভেন্ট হ্যান্ডলারগুলি যেভাবে সঞ্চয় করেন তা বেছে নিতে আপনি নির্দ্বিধায় রয়েছেন (নোট করুন ইভেন্ট হ্যান্ডলারগুলি ইভেন্টের ধরণের উদাহরণস্বরূপ , যা পূর্ববর্তী পর্যবেক্ষণ থেকে বাধ্যতামূলকভাবে একটি প্রতিনিধি প্রকার --- )। তবে, আপনি সেই ইভেন্ট হ্যান্ডলারগুলি (যা প্রতিনিধিদের উদাহরণ হিসাবে) কোনও ডেটা স্ট্রাকচারে যেমন একটি বা অন্য কোনও বা অন্য কোনও, বা এমনকি কোনও সমর্থনকারী প্রতিনিধি ক্ষেত্রে সংরক্ষণ করতে পারেন। তবে ভুলে যাবেন না যে আপনি কোনও প্রতিনিধি ক্ষেত্রটি ব্যবহার করা বাধ্যতামূলক নয়।List
Dictionary
। নেট এর একটি ইভেন্ট হ'ল একটি অ্যাড পদ্ধতি এবং একটি সরান পদ্ধতির একটি মনোনীত সংমিশ্রণ, উভয়ই কিছু নির্দিষ্ট ধরণের প্রতিনিধি আশা করে। সি # এবং vb.net উভয়ই অ্যাড এবং রিমুথ পদ্ধতিগুলির জন্য কোড স্বয়ংক্রিয়ভাবে উত্পন্ন করতে পারে যা ইভেন্টের সাবস্ক্রিপশন ধরে রাখার জন্য কোনও প্রতিনিধিকে সংজ্ঞায়িত করবে এবং সেই সাবস্ক্রিপশন প্রতিনিধি থেকে / পাসের প্রতিনিধিটিকে যুক্ত / সরিয়ে ফেলবে। VB.net এছাড়াও সাবস্ক্রিপশন তালিকার অনুরোধ করতে কোডটি (RaiseEvent বিবৃতি সহ) স্বয়ংক্রিয়ভাবে উত্পন্ন করবে যদি তা কেবল খালি না থাকে; কোনও কারণে, সি # উত্তরোত্তর উত্পন্ন করে না।
মনে রাখবেন যে কোনও মাল্টিকাস্ট ডেলিগেট ব্যবহার করে ইভেন্টের সদস্যতাগুলি পরিচালনা করা সাধারণ বিষয়, এটি করার একমাত্র উপায় এটি নয়। জনগণের দৃষ্টিকোণ থেকে, কোনও ইভেন্টের গ্রাহককে কোনও বিষয়টিকে কীভাবে ইভেন্টগুলি পেতে চায় তা কীভাবে জানাতে হয় তা জানতে হবে, তবে ইভেন্টগুলি উত্থাপনের জন্য প্রকাশক কী পদ্ধতি ব্যবহার করবেন তা জানার দরকার নেই। এছাড়াও নোট করুন যে কেউ। নেট এ ইভেন্টের ডেটা কাঠামোটি সংজ্ঞায়িত করার সময় স্পষ্টতই মনে করেছিল যে তাদের উত্থাপনের কোনও সরকারী উপায় থাকতে হবে, তবে সি # বা ভিবি নেটও এই বৈশিষ্ট্যটি ব্যবহার করে না।
সহজ পদ্ধতিতে ইভেন্ট সম্পর্কে সংজ্ঞা দেওয়া:
ইভেন্ট দুটি বিধিনিষেধ সহ একটি প্রতিনিধিদের জন্য একটি রেফারেন্স
দুটির উপরে প্রতিনিধিদের জন্য দুর্বল পয়েন্টগুলি রয়েছে এবং এটি ইভেন্টে সম্বোধন করা হয়। ফিডলারের পার্থক্য দেখানোর জন্য কোডের সম্পূর্ণ নমুনাটি এখানে https://dotnetfiddle.net/5iR3fB ।
ইভেন্ট এবং ডেলিগেট এবং ক্লায়েন্ট কোডের মধ্যে মন্তব্যটি টগল করুন যা পার্থক্যটি বোঝার জন্য ডেলিগেট করতে মানগুলিকে অনুরোধ করে / নির্ধারণ করে
এখানে ইনলাইন কোড।
/*
This is working program in Visual Studio. It is not running in fiddler because of infinite loop in code.
This code demonstrates the difference between event and delegate
Event is an delegate reference with two restrictions for increased protection
1. Cannot be invoked directly
2. Cannot assign value to delegate reference directly
Toggle between Event vs Delegate in the code by commenting/un commenting the relevant lines
*/
public class RoomTemperatureController
{
private int _roomTemperature = 25;//Default/Starting room Temperature
private bool _isAirConditionTurnedOn = false;//Default AC is Off
private bool _isHeatTurnedOn = false;//Default Heat is Off
private bool _tempSimulator = false;
public delegate void OnRoomTemperatureChange(int roomTemperature); //OnRoomTemperatureChange is a type of Delegate (Check next line for proof)
// public OnRoomTemperatureChange WhenRoomTemperatureChange;// { get; set; }//Exposing the delegate to outside world, cannot directly expose the delegate (line above),
public event OnRoomTemperatureChange WhenRoomTemperatureChange;// { get; set; }//Exposing the delegate to outside world, cannot directly expose the delegate (line above),
public RoomTemperatureController()
{
WhenRoomTemperatureChange += InternalRoomTemperatuerHandler;
}
private void InternalRoomTemperatuerHandler(int roomTemp)
{
System.Console.WriteLine("Internal Room Temperature Handler - Mandatory to handle/ Should not be removed by external consumer of ths class: Note, if it is delegate this can be removed, if event cannot be removed");
}
//User cannot directly asign values to delegate (e.g. roomTempControllerObj.OnRoomTemperatureChange = delegateMethod (System will throw error)
public bool TurnRoomTeperatureSimulator
{
set
{
_tempSimulator = value;
if (value)
{
SimulateRoomTemperature(); //Turn on Simulator
}
}
get { return _tempSimulator; }
}
public void TurnAirCondition(bool val)
{
_isAirConditionTurnedOn = val;
_isHeatTurnedOn = !val;//Binary switch If Heat is ON - AC will turned off automatically (binary)
System.Console.WriteLine("Aircondition :" + _isAirConditionTurnedOn);
System.Console.WriteLine("Heat :" + _isHeatTurnedOn);
}
public void TurnHeat(bool val)
{
_isHeatTurnedOn = val;
_isAirConditionTurnedOn = !val;//Binary switch If Heat is ON - AC will turned off automatically (binary)
System.Console.WriteLine("Aircondition :" + _isAirConditionTurnedOn);
System.Console.WriteLine("Heat :" + _isHeatTurnedOn);
}
public async void SimulateRoomTemperature()
{
while (_tempSimulator)
{
if (_isAirConditionTurnedOn)
_roomTemperature--;//Decrease Room Temperature if AC is turned On
if (_isHeatTurnedOn)
_roomTemperature++;//Decrease Room Temperature if AC is turned On
System.Console.WriteLine("Temperature :" + _roomTemperature);
if (WhenRoomTemperatureChange != null)
WhenRoomTemperatureChange(_roomTemperature);
System.Threading.Thread.Sleep(500);//Every second Temperature changes based on AC/Heat Status
}
}
}
public class MySweetHome
{
RoomTemperatureController roomController = null;
public MySweetHome()
{
roomController = new RoomTemperatureController();
roomController.WhenRoomTemperatureChange += TurnHeatOrACBasedOnTemp;
//roomController.WhenRoomTemperatureChange = null; //Setting NULL to delegate reference is possible where as for Event it is not possible.
//roomController.WhenRoomTemperatureChange.DynamicInvoke();//Dynamic Invoke is possible for Delgate and not possible with Event
roomController.SimulateRoomTemperature();
System.Threading.Thread.Sleep(5000);
roomController.TurnAirCondition (true);
roomController.TurnRoomTeperatureSimulator = true;
}
public void TurnHeatOrACBasedOnTemp(int temp)
{
if (temp >= 30)
roomController.TurnAirCondition(true);
if (temp <= 15)
roomController.TurnHeat(true);
}
public static void Main(string []args)
{
MySweetHome home = new MySweetHome();
}
}
ডেলিগেট হ'ল টাইপ-সেফ ফাংশন পয়েন্টার। ইভেন্ট প্রতিনিধি ব্যবহার করে প্রকাশক-গ্রাহক ডিজাইন প্যাটার্নের একটি বাস্তবায়ন।
আপনি যদি ইন্টারমিডিয়েট ল্যাঙ্গুয়েজ চেক করেন, আপনি জেনে নিতে পারবেন। নেট সংকলক কিছু বিল্ট-ইন ফাংশন সহ আইএল-এর সিলড ক্লাসে রূপান্তরকারী প্রতিনিধিদের রূপান্তর করুন, যেমন ইনভোক, বিজনভোক, এন্ড ইনভেক এবং অন্য শ্রেণীর উত্তরাধিকার সূত্রে প্রাপ্ত প্রতিনিধি শ্রেণি, সম্ভবত "সিস্টেমমল্টিকাস্ট" নামে পরিচিত। আমার ধারণা ইভেন্টটি অতিরিক্ত কিছু সম্পত্তি সহ ডেলিগেটের একটি শিশু শ্রেণি।
ইভেন্ট এবং ডেলিগেটের উদাহরণগুলির মধ্যে পার্থক্য হ'ল আপনি ঘোষণার বাইরে ইভেন্ট চালাতে পারবেন না। আপনি ক্লাস এ-তে কোনও ইভেন্ট ঘোষণা করলে আপনি কেবল এ-ক্লাস এ-তে এই ইভেন্টটি চালাতে পারবেন যদি আপনি ক্লাস এ-তে কোনও প্রতিনিধি ঘোষণা করেন তবে আপনি এই প্রতিনিধিটি যে কোনও জায়গায় ব্যবহার করতে পারবেন। আমি মনে করি এটি তাদের মধ্যে একটি প্রধান পার্থক্য