Lazy T
מחלקת ה-Lazy<T> נותנת לנו יכולת ליצור מופעים רק כשאנחנו צריכים אותם.
המאפיין Value יוצר את המחלקה.
ואם אנחנו רוצים לבדוק אם המופע נוצר ניתן לקרוא את IsValueCreated.
1 | Lazy<int> myInt = new Lazy<int>(); |
העקרונות מאחורי המחלקה
שימוש יעיל במשאבים.
יצירת מופעים בצורה מסונכרנת.
- להשתמש במחלקה קיימת כדי לאתחל משתנה אשר צריך
Thread safety(נדבר על זה עוד מעט). - לאתחל משתנה גלובלי סטטי - בגלל היכולת שלו להיות
Thread safe. - כשמשאב הוא יקר והשימוש בו לא רב
- כשהמשאב הוא יקר וצריך לבצע פעולה כלשהי כדי לאתחל אותו (כמו לקרוא מקובץ).
כיצד ליצור את המחלקה
מחלקת Lazy יכולה להיות מאותחלת במגוון דרכים:
Lazy - בנאי ריק
הבנאי הריק יוצר משתנה אשר יש לו בנאי ריק.
1 | class MyClass |
Lazy<T>(bool isThreadSafe) - עם סנכרון
ניתן להעביר בוליאני שאומר אם אנחנו רוצים שה-Lazy יהיה בעל הגנה לתהליכונים מרובים או לא.
המחיר?
משתנים שהם Thread-Safe סובלים מבעיות ביצועים.
1 | class MyClass |
Lazy<T>(LazyThreadSafetyMode) - סוג סנכרון
ניתן לקנפג את ההתנהגות בהתאם למצב שאנו רוצים.
LazyThreadSafetyMode.None
אין Thread safety בכלל.
מצב זה גורם לריבוי תהליכונים להיות - Undefined.
לכן אם יש לכם יותר מתהליכון אחד אל תשתמשו בזה!
אולם - זה מהיר יותר אז אם אתם יודעים שרק תהליכון אחד ישתמש ב-Lazy ניתן להשתמש ב-None.
LazyThreadSafetyMode.PublicationOnly
עבור תהליכונים רבים - הראשון שמשלים את תהליך האתחול הוא יסיים את התהליך.
הנה דוגמא מעניינת - מה לדעתכם יודפס?
1 | public class MyClass |
זה יודפס 10 פעמים!
1 | MyClass834 |
LazyThreadSafetyMode.ExecutionAndPublication
היצירה וההשמה של המופע יהיה באופן מוגן ומלא כך שרק תהליכון אחד יוכל ליצור את המופע.
Lazy<T>(Func<T> function) - בניית המופע
הבנאי ייקבל מתודת Factory אשר יודעת כיצד ליצור משתנה.
הבחירה הנכונה בבנאי זה כאשר אנו רוצים לבצע פעולה לפני יצירת המופע.
זאת כדי להימנע מפעולות חיצוניות או מורכבות בתוך הבנאים.
למשל אם נרצה לקרוא מקובץ קודם:
1 | public class MyClass |
Lazy(T value) - ערך מאותחל מראש
הבנאי מקבל ערך מאותחל מראש.
בשביל מה צריך את זה? כדי לסנכרן תהליכונים.
זו לא הגישה המקובלת אך אם צריך לאתחל Lazy עם ערך מראש אז זו הדרך.
1 | class MyClass |
דוגמאות לשימוש
יצירת סינגלטון
כמקובל יצירת סינגלטון סטטי נעשתה בצורה הזו:
1 | public class MyHandler |
Lazy חוסך לנו את כל זה!
1 | public class MyHandler |
חסכון במשאב יקר
1 | public class ExpensiveClass |
יצירת מחלקות
בדוגמא הבאה הקוד הוא צד לקוח אשר רוצה לפתוח ולשמר חיבור.
מחלקת החיבור לא שלנו ולכן אנחנו לא יכולים לשנות אותה
1 | public class Connection |
בתצורה הזו הקוד מוודא שהמופע נוצר ויש לנו מקום אחד בלבד שאחראי לאיך ליצור אותו.
עצלנות זוהי דרך מעולה לנצל ביעילות רק מה שדרוש באותו רגע.
איזה עוד מחלקות מממשות את העקרון הזה?
רמז - Enumerable!
תודה על הקריאה!