1
00:00.110 --> 00:00.920
خوش برگشتید.

2
00:00.920 --> 00:05.600
تو این ویدیو می‌خوایم ببینیم چطور می‌تونیم یک multicast delegate رو به شکل ایمن فراخوانی کنیم.

3
00:05.600 --> 00:08.630
بنابراین قراره یک متد به اسم **InvokeSafely** بسازیم.

4
00:08.630 --> 00:13.520
پس **static void invoke safely**.

5
00:13.520 --> 00:24.530
و چیزی که می‌خوام بگم اینه که log handler رو دریافت می‌کنم، به علاوه یک پیام (message) که می‌خوام نمایش بدم. پس **string message**.

6
00:24.530 --> 00:40.540
بسیار خب. و این متد در اینجا، کاری که باید انجام بده اینه که یک log handler موقت ایجاد می‌کنه. خب.

7
00:40.540 --> 00:51.340
و بعد می‌گم اگه **temp log handler** نال (null) نبود، از **temp log handler** برای ارسال پیام یا نمایش پیام استفاده کن.

8
00:51.340 --> 00:55.250
پس کاری که می‌کنه فقط log handler رو صدا می‌زنه. اوکی.

9
00:55.250 --> 01:08.810
بنابراین حالا کاری که می‌تونیم انجام بدیم اینه که به جای صدا زدن log handler اینجا، می‌گیم **invoke safely**. و بعد log handler و همچنین پیام رو پاس می‌دیم.

10
01:08.810 --> 01:15.080
و پیام ما می‌تونه مثلاً "بعد از حذف log to file" باشه، اوکی؟

11
01:15.080 --> 01:22.270
پس این فقط یک راه... خب یک راه امن‌تر برای انجام دادنشه.

12
01:22.570 --> 01:25.600
پس بذارید این رو کامنت کنم.

13
01:25.600 --> 01:33.100
و حالا داریم به شکل ایمن فراخوانی می‌کنیم و بذارید اجراش کنیم و می‌بینیم **console log** هنوز خوب کار می‌کنه. اوکی.

14
01:33.100 --> 01:38.290
اما این مشکلمون رو یا خطایی که اینجا داریم، یا نه خطای دیگری رو، اما **هشدارمون** رو حل نمی‌کنه.

15
01:38.290 --> 01:48.230
پس چطور بفهمم چه آیتم‌هایی داخل یک multicast delegate هستن؟ چه متدهایی داخلش هستن؟ خب، متدی به اسم **InvocationList** وجود داره.

16
01:48.230 --> 01:58.190
پس اگه می‌خواستیم مطمئن بشیم که فراخوانی به شکلی حتی ایمن‌تر انجام می‌شه، می‌تونیم از **try and catch** استفاده کنیم.

17
01:58.190 --> 02:07.040
پس بعد از اینکه loggerمون رو ساختیم، بذارید اینجا انجام بدیم. اینجا جاییه که داریم multicast delegate رو فراخوانی می‌کنیم.

18
02:07.040 --> 02:10.280
پس به جای اینکه به شکل ناایمن انجامش بدیم، به شکل ایمن انجامش می‌دیم.

19
02:10.280 --> 02:22.940
و برای انجام اون، می‌تونیم از **for each** در اینجا استفاده کنیم و می‌تونیم بگیم **LogHandler handler in** و اینجا **logHandler.GetInvocationList()**، اوکی.

20
02:22.940 --> 02:31.490
پس این **GetInvocationList** آیتم‌های داخل delegate رو به ما می‌ده. پس یک **delegate array** برمی‌گردونه.

21
02:31.490 --> 02:34.220
اینجا می‌بینیدش. **delegate** داخل کروشه.

22
02:34.220 --> 02:49.310
پس می‌تونم بگم **try handler** و بعد هرچیزی که می‌خوایم بگیم. پس "Event occurred with error handling" (رویداد با مدیریت خطا رخ داد). و در صورتی که با خطا مواجه بشیم، اونجاست که **exception** (استثنا) رو **catch** می‌کنیم.

23
02:49.310 --> 02:58.100
می‌گیم: "Exception caught with" به علاوه هرچیزی که پیام هست. پس **plus x message**، اوکی.

24
02:58.100 --> 03:11.800
پس این شکلیه که می‌تونیم مطمئن بشیم آیتم‌های داخل log handler فقط یک بار فراخوانی می‌شن، و اینکه واقعاً چیزی برای فراخوانی وجود داره، که اساساً این خط در اینجاست.

25
03:11.800 --> 03:22.060
بنابراین به جای استفاده از این خط، می‌تونستیم از این حلقه **for each** استفاده کنیم که در اون با هر تک تک آیتمی که متنیه که می‌خوایم پاس بدیم، فراخوانی می‌کنیم. اوکی.

26
03:22.060 --> 03:26.670
پس با این **for each** از تمام آیتم‌های لاگ شده رد می‌شیم.

27
03:26.670 --> 03:34.350
بنابراین در این حالت، ما دو آیتم در لیست فراخوانی داریم، اوکی. ما **LogToFile** و همچنین **LogToConsole** رو داریم.

28
03:34.350 --> 03:42.780
حالا کاری که می‌تونیم انجام بدیم اینه که بگیم فقط اگر **LogToFile** داخل log handler بود، بذارید حذفش کنیم.

29
03:42.780 --> 03:46.470
پس برای اطمینان از اون می‌تونیم کار زیر رو انجام بدیم.

30
03:46.470 --> 04:03.940
می‌تونیم یک متد دیگه بسازیم: **static bool** که اسمش رو می‌ذارم **IsMethodInDelegate**. و اینجا می‌تونیم log handler و همچنین متد log handler رو پاس بدیم. پس **LogHandler method**.

31
04:04.000 --> 04:06.100
اوکی پس این کمی عجیب به نظر می‌رسه.

32
04:06.100 --> 04:14.880
اما اساساً چیزی که داره اتفاق می‌افته اینه که ما log handler خودش رو با هر متدی که از نوع **LogHandler** باشه مقایسه می‌کنیم. اوکی.

33
04:14.880 --> 04:22.000
چون log handler اگه بهش نگاه کنیم، **delegate** ماست.

34
04:22.000 --> 04:31.050
پس به طرز جالبی متدی رو که از نوع اون delegate هست، و همچنین خود delegate رو مقایسه می‌کنیم، که می‌تونه چندین متد بهش اختصاص داده شده باشه.

35
04:31.050 --> 04:44.500
پس کاری که این متد انجام می‌ده اینه که اول از همه بررسی می‌کنه که آیا log handler نال (null) هست؟ اگه اینطور باشه، **false** رو برمی‌گردونیم و در بلوک **else**...

36
04:44.500 --> 04:52.780
اساساً ما نیازی به بلوک **else** نداریم، چون در غیر این صورت، اگه این اجرا بشه، ما به هر حال از این متد خارج می‌شیم چون از قبل چیزی رو برگردوندیم.

37
04:52.780 --> 05:00.460
اما در غیر این صورت، می‌گیم: **for each var d in log handler.GetInvocationList()**.

38
05:00.460 --> 05:14.670
اگه **d** مساوی با **method** باشه، پس **true** رو برگردون و در غیر این صورت اگه این اتفاق نیفتاد، یعنی اگه در کل لیست این اتفاق نیفتاد، **false** رو برگردون.

39
05:14.670 --> 05:28.260
پس حالا اینجا می‌تونیم اون رو به یک delegate **cast** کنیم اگه واقعاً می‌خواستیم مطمئن بشیم، اینطوری: **delegate method**. و بعد اون رو به شکل واقعاً واضحی داریم، چون **method** از نوع **delegate** هست.

40
05:28.260 --> 05:31.550
اما ما واقعاً مطمئن می‌شیم که اون رو به فرمت درست **cast** می‌کنیم.

41
05:31.550 --> 05:43.280
پس داریم **D** رو که یک delegate هست مقایسه می‌کنیم، چون **GetInvocationList** یک **delegate array** برمی‌گردونه. پس هر آیتم تکی در **delegate array** یک **delegate** خواهد بود.

42
05:43.280 --> 05:48.920
پس این می‌تونست **delegate** باشه. می‌تونستیم بهش **delegate** بگیم. اما اسم خوبی نیست چون **delegate** از قبل یک نام داخلی در C\# هست.

43
05:48.920 --> 05:51.260
پس نمی‌تونیم از اون استفاده کنیم.

44
05:51.260 --> 05:55.830
اما می‌تونیم بهش **D** بگیم. و بعد متد رو مقایسه می‌کنیم که بعد اون رو به یک **delegate** **cast** می‌کنیم و اون دو رو مقایسه می‌کنیم.

45
05:55.830 --> 06:05.730
و اگه اونها یکسان باشن، می‌دونیم که delegate ما که می‌خواستیم حذفش کنیم، داخل multicast delegate هست.

46
06:05.730 --> 06:19.230
پس کاری که می‌تونیم بگیم اینه که قبل از حذف این، می‌تونیم بررسی کنیم که آیا **logger.LogToFile** هست. و بذارید در واقع اون رو بذارم.

47
06:19.250 --> 06:26.090
پس اگه متد **IsMethodInDelegate** چطور صداش می‌زنیم؟ **IsMethodInDelegate**. اول logger رو پاس می‌دیم.

48
06:26.090 --> 06:36.260
پس log handlerمون چطور صداش می‌زنیم؟ log handlerمون رو پاس می‌دیم و متدی رو پاس می‌دیم که **logger.LogToFile** هست.

49
06:36.260 --> 06:43.820
پس اگه اینطور باشه، اگه این **true** باشه، می‌تونیم بگیم log handler، **LogToFile** رو حذف کن.

50
06:43.820 --> 06:55.860
پس کاری که می‌تونیم اینجا برای واضح‌تر شدن بگیم اینه که می‌تونیم بگیم: **LogToFile method removed**. و در بلوک **else** می‌تونیم بگیم: **LogToFile method not found**.

51
06:55.860 --> 07:00.990
پس **LogToFile method not found**. اوکی.

52
07:00.990 --> 07:06.540
پس فرض کنیم ما هرگز متد **LogToFile** رو در این حالت اضافه نکردیم.

53
07:06.540 --> 07:12.410
پس بذارید اجراش کنیم و باید ببینیم که می‌گه: **LogToFile not found**. پس **LogToFile method not found**.

54
07:12.410 --> 07:16.160
و حالا بذارید دوباره اجراش کنیم. اما این بار داخلش هست.

55
07:16.160 --> 07:23.150
و می‌بینیم: **LogToFile method removed**. و بعد می‌گه: **console after removing LogToFile**، اوکی.

56
07:23.150 --> 07:26.030
پس این یه چیز کوچیک بود.

57
07:26.030 --> 07:31.520
می‌بینید که هشدارها هنوز از بین نمی‌رن. اما ما واقعاً مطمئن شدیم که همه چیز خوبه.

58
07:31.520 --> 07:41.130
پس حالا می‌تونید واقعاً مطمئن بشید که **if log handler not equal null** (اگر log handler نال نبود)، فقط در اون صورت این **InvokeSafely** رو اجرا کن.

59
07:41.160 --> 07:57.570
با وجود اینکه **InvokeSafely** ما از قبل این کار رو انجام می‌ده، اوکی. اوکی، می‌گم این یک نکته حاشیه‌ای کوچیک بود که دیدید چطور می‌تونید delegateها رو و اینکه چه متدهایی به یک multicast delegate اختصاص داده شدن، مدیریت کنید.

60
07:57.570 --> 07:59.460
پس این برای این ویدیو کافیه.

61
07:59.460 --> 08:00.420
تو ویدیوی بعدی می‌بینمتون.