שחוסך הרבה מתודות סתמיות שרק נועדו בשביל להקפיץ אירועים.
עוד יותר מזה, אם אנחנו לא נוהגים להקפיץ אירועים כפי שציינתי עכשיו, אלא בדרך יותר מטורפת (למשל עם כל מיני Interlockים וכדומה), נצטרך לכתוב את הקוד של הקפצת האירוע רק פעם אחת 😃
החסרון בשיטה זו, זה שאמנם אנחנו חוסכים מתודות, אך בכל הקפצה של האירוע, אנחנו צריכים לציין את this. זה לא נורא, כי גם ככה היינו רוצים להקפיץ אירוע בשיטה הטבעית הבאה:
ראינו שאם יש לנו מתודה גנרית, ניתן להפוך אותה לExtension method:
1
publicstatic T First<T>(this IEnumerable<T> enumerable)
ולקרוא לה כך:
1
2
3
4
5
6
7
8
9
10
11
IEnumerable<string> strings =
newstring[]
{
"A new hope",
"The empire strikes back",
"The return of the Jedi"
};
string firstMovie = strings.First<string>(); // A new hope
char firstLetter = "The first letter is 'T'".First<char>();
ראינו בעבר (טיפ מספר 28) שאם יש לנו מתודה גנרית, ניתן לקרוא לה לרוב implicity, בלי ציון הפרמטרים:
1
2
3
string firstMovie = Utilities.First(strings); // A new hope
char firstLetter = Utilities.First("The first letter is 'T'");
הדבר נכון גם לגבי Extension Methods גנריים!
מאחר והקוד מתקמפל לאותו קוד נוכל לכתוב את הקוד הבא:
1
2
3
string firstMovie = strings.First(); // A new hope
char firstLetter = "The first letter is 'T'".First();
שימו לב ליופי שבדבר!
אם בפעם שעברה ראינו "שהוספנו" מתודה לכל IEnumerable<T> בלי לדעת בכלל מהו T, כעת אנחנו "הוספנו" מתודה לכל IEnumerable<T> ואנחנו בכלל לא צריכים לציין מהו T.
הדבר מאפשר לנו לקרוא בצורה מאוד נקייה לUtilities. שימו לב להבדל בקריאות בין הכתיבה הסטטית, לכתיבה של אתמול, לכתיבה החדשה.
כל המגבלות שאמרנו ביום ראשון על Extension Methods חלות גם פה (אי אפשר שניים עם אותה חתימה באותו שם באותו namespace וכו’), וכן המגבלות של הקומפיילר לפענח לבדו מהו T. (ראו גם הטיפ היום מספר 28)
באופן כללי, הממשק הומצא כדי לנקות משאבים שהם unmanaged (למשל גישה לקבצים, פקדים וכו’) –
הGarbage Collector מנקה באופן אוטומטי אובייקטים שהם managed ברגע שהם לא נמצאים יותר בשימוש, אבל אי אפשר לדעת מתי הוא יפעל. פרט לזאת, הGarbage Collector לא מכיר משאבים שהם unmanaged.
המטרה של הממשק היא לנקות את המשאבים הunmanaged באופן ייזום. מחזיק של אובייקט יכול לקרוא לDispose כאשר אין לו צורך באובייקט יותר.
מימוש:
מומלץ לממש במידה והאובייקט שלנו משתמש בעצמו במשאבים שהם unmanaged, (קבצים, פקדים, Threadים וכו’), גם אם הוא משתמש בעטיפות שלהם.
בנוסף, מומלץ לממש אם ברצונכם לאפשר לקרוא באופן ייזום לניקיון של האובייקט.
שימוש:
מומלץ להשתמש בממשק באמצעות בלוק של try וfinally, למשל: