خوش برگشتید.
تو این ویدیو می‌خوایم ببینیم چطور می‌تونیم یک multicast delegate رو به شکل ایمن فراخوانی کنیم.
بنابراین قراره یک متد به اسم **InvokeSafely** بسازیم.
پس **static void invoke safely**.
و چیزی که می‌خوام بگم اینه که log handler رو دریافت می‌کنم، به علاوه یک پیام (message) که می‌خوام نمایش بدم. پس **string message**.
بسیار خب. و این متد در اینجا، کاری که باید انجام بده اینه که یک log handler موقت ایجاد می‌کنه. خب.
و بعد می‌گم اگه **temp log handler** نال (null) نبود، از **temp log handler** برای ارسال پیام یا نمایش پیام استفاده کن.
پس کاری که می‌کنه فقط log handler رو صدا می‌زنه. اوکی.
بنابراین حالا کاری که می‌تونیم انجام بدیم اینه که به جای صدا زدن log handler اینجا، می‌گیم **invoke safely**. و بعد log handler و همچنین پیام رو پاس می‌دیم.
و پیام ما می‌تونه مثلاً "بعد از حذف log to file" باشه، اوکی؟
پس این فقط یک راه... خب یک راه امن‌تر برای انجام دادنشه.
پس بذارید این رو کامنت کنم.
و حالا داریم به شکل ایمن فراخوانی می‌کنیم و بذارید اجراش کنیم و می‌بینیم **console log** هنوز خوب کار می‌کنه. اوکی.
اما این مشکلمون رو یا خطایی که اینجا داریم، یا نه خطای دیگری رو، اما **هشدارمون** رو حل نمی‌کنه.
پس چطور بفهمم چه آیتم‌هایی داخل یک multicast delegate هستن؟ چه متدهایی داخلش هستن؟ خب، متدی به اسم **InvocationList** وجود داره.
پس اگه می‌خواستیم مطمئن بشیم که فراخوانی به شکلی حتی ایمن‌تر انجام می‌شه، می‌تونیم از **try and catch** استفاده کنیم.
پس بعد از اینکه loggerمون رو ساختیم، بذارید اینجا انجام بدیم. اینجا جاییه که داریم multicast delegate رو فراخوانی می‌کنیم.
پس به جای اینکه به شکل ناایمن انجامش بدیم، به شکل ایمن انجامش می‌دیم.
و برای انجام اون، می‌تونیم از **for each** در اینجا استفاده کنیم و می‌تونیم بگیم **LogHandler handler in** و اینجا **logHandler.GetInvocationList()**، اوکی.
پس این **GetInvocationList** آیتم‌های داخل delegate رو به ما می‌ده. پس یک **delegate array** برمی‌گردونه.
اینجا می‌بینیدش. **delegate** داخل کروشه.
پس می‌تونم بگم **try handler** و بعد هرچیزی که می‌خوایم بگیم. پس "Event occurred with error handling" (رویداد با مدیریت خطا رخ داد). و در صورتی که با خطا مواجه بشیم، اونجاست که **exception** (استثنا) رو **catch** می‌کنیم.
می‌گیم: "Exception caught with" به علاوه هرچیزی که پیام هست. پس **plus x message**، اوکی.
پس این شکلیه که می‌تونیم مطمئن بشیم آیتم‌های داخل log handler فقط یک بار فراخوانی می‌شن، و اینکه واقعاً چیزی برای فراخوانی وجود داره، که اساساً این خط در اینجاست.
بنابراین به جای استفاده از این خط، می‌تونستیم از این حلقه **for each** استفاده کنیم که در اون با هر تک تک آیتمی که متنیه که می‌خوایم پاس بدیم، فراخوانی می‌کنیم. اوکی.
پس با این **for each** از تمام آیتم‌های لاگ شده رد می‌شیم.
بنابراین در این حالت، ما دو آیتم در لیست فراخوانی داریم، اوکی. ما **LogToFile** و همچنین **LogToConsole** رو داریم.
حالا کاری که می‌تونیم انجام بدیم اینه که بگیم فقط اگر **LogToFile** داخل log handler بود، بذارید حذفش کنیم.
پس برای اطمینان از اون می‌تونیم کار زیر رو انجام بدیم.
می‌تونیم یک متد دیگه بسازیم: **static bool** که اسمش رو می‌ذارم **IsMethodInDelegate**. و اینجا می‌تونیم log handler و همچنین متد log handler رو پاس بدیم. پس **LogHandler method**.
اوکی پس این کمی عجیب به نظر می‌رسه.
اما اساساً چیزی که داره اتفاق می‌افته اینه که ما log handler خودش رو با هر متدی که از نوع **LogHandler** باشه مقایسه می‌کنیم. اوکی.
چون log handler اگه بهش نگاه کنیم، **delegate** ماست.
پس به طرز جالبی متدی رو که از نوع اون delegate هست، و همچنین خود delegate رو مقایسه می‌کنیم، که می‌تونه چندین متد بهش اختصاص داده شده باشه.
پس کاری که این متد انجام می‌ده اینه که اول از همه بررسی می‌کنه که آیا log handler نال (null) هست؟ اگه اینطور باشه، **false** رو برمی‌گردونیم و در بلوک **else**...
اساساً ما نیازی به بلوک **else** نداریم، چون در غیر این صورت، اگه این اجرا بشه، ما به هر حال از این متد خارج می‌شیم چون از قبل چیزی رو برگردوندیم.
اما در غیر این صورت، می‌گیم: **for each var d in log handler.GetInvocationList()**.
اگه **d** مساوی با **method** باشه، پس **true** رو برگردون و در غیر این صورت اگه این اتفاق نیفتاد، یعنی اگه در کل لیست این اتفاق نیفتاد، **false** رو برگردون.
پس حالا اینجا می‌تونیم اون رو به یک delegate **cast** کنیم اگه واقعاً می‌خواستیم مطمئن بشیم، اینطوری: **delegate method**. و بعد اون رو به شکل واقعاً واضحی داریم، چون **method** از نوع **delegate** هست.
اما ما واقعاً مطمئن می‌شیم که اون رو به فرمت درست **cast** می‌کنیم.
پس داریم **D** رو که یک delegate هست مقایسه می‌کنیم، چون **GetInvocationList** یک **delegate array** برمی‌گردونه. پس هر آیتم تکی در **delegate array** یک **delegate** خواهد بود.
پس این می‌تونست **delegate** باشه. می‌تونستیم بهش **delegate** بگیم. اما اسم خوبی نیست چون **delegate** از قبل یک نام داخلی در C\# هست.
پس نمی‌تونیم از اون استفاده کنیم.
اما می‌تونیم بهش **D** بگیم. و بعد متد رو مقایسه می‌کنیم که بعد اون رو به یک **delegate** **cast** می‌کنیم و اون دو رو مقایسه می‌کنیم.
و اگه اونها یکسان باشن، می‌دونیم که delegate ما که می‌خواستیم حذفش کنیم، داخل multicast delegate هست.
پس کاری که می‌تونیم بگیم اینه که قبل از حذف این، می‌تونیم بررسی کنیم که آیا **logger.LogToFile** هست. و بذارید در واقع اون رو بذارم.
پس اگه متد **IsMethodInDelegate** چطور صداش می‌زنیم؟ **IsMethodInDelegate**. اول logger رو پاس می‌دیم.
پس log handlerمون چطور صداش می‌زنیم؟ log handlerمون رو پاس می‌دیم و متدی رو پاس می‌دیم که **logger.LogToFile** هست.
پس اگه اینطور باشه، اگه این **true** باشه، می‌تونیم بگیم log handler، **LogToFile** رو حذف کن.
پس کاری که می‌تونیم اینجا برای واضح‌تر شدن بگیم اینه که می‌تونیم بگیم: **LogToFile method removed**. و در بلوک **else** می‌تونیم بگیم: **LogToFile method not found**.
پس **LogToFile method not found**. اوکی.
پس فرض کنیم ما هرگز متد **LogToFile** رو در این حالت اضافه نکردیم.
پس بذارید اجراش کنیم و باید ببینیم که می‌گه: **LogToFile not found**. پس **LogToFile method not found**.
و حالا بذارید دوباره اجراش کنیم. اما این بار داخلش هست.
و می‌بینیم: **LogToFile method removed**. و بعد می‌گه: **console after removing LogToFile**، اوکی.
پس این یه چیز کوچیک بود.
می‌بینید که هشدارها هنوز از بین نمی‌رن. اما ما واقعاً مطمئن شدیم که همه چیز خوبه.
پس حالا می‌تونید واقعاً مطمئن بشید که **if log handler not equal null** (اگر log handler نال نبود)، فقط در اون صورت این **InvokeSafely** رو اجرا کن.
با وجود اینکه **InvokeSafely** ما از قبل این کار رو انجام می‌ده، اوکی. اوکی، می‌گم این یک نکته حاشیه‌ای کوچیک بود که دیدید چطور می‌تونید delegateها رو و اینکه چه متدهایی به یک multicast delegate اختصاص داده شدن، مدیریت کنید.
پس این برای این ویدیو کافیه.
تو ویدیوی بعدی می‌بینمتون.