ראינו בעבר (טיפ מספר 89) כי בC# 3.0 נוספה אפשרות להגדיר Properties בצורה יותר נוחה.
הדבר עובד טוב למחלקות, אך האם הוא עובד גם לstructים?
במבט ראשון, נראה שזה עובד:
|
|
הקוד מתקמפל ועובד.
כעת נקשה על העניין, נהפוך את הsetterים להיות private:
|
|
עדיין מתקמפל, אבל עכשיו כבר אי אפשר לאתחל את הProperties מבחוץ.
אז נוסיף Constructor שיאתחל לנו אותם:
|
|
אבל עכשיו נראה שהקוד לא מתקמפל יותר:
Backing field for automatically implemented property ‘Point3D.Z’ must be fully assigned before control is returned to the caller. Consider calling the default constructor from a constructor initializer.
Backing field for automatically implemented property ‘Point3D.Y’ must be fully assigned before control is returned to the caller. Consider calling the default constructor from a constructor initializer.
Backing field for automatically implemented property ‘Point3D.X’ must be fully assigned before control is returned to the caller. Consider calling the default constructor from a constructor initializer.
The ‘this’ object cannot be used before all of its fields are assigned to
מה קורה פה?
זוכרים שאתמול הזכרנו שבConstructor שאינו דיפולטי של struct אנחנו מחויבים לאתחל את כל השדות?
ובכן, הAuto-Properties בעצם יוצרים לנו שדות מאחורי הקלעים, שאותם לא איתחלנו בConstructor. לכן הקוד אינו מתקמפל.
איך נוכל לפתור את הבעיה?
קיימות מספר אופציות:
- אופציה ראשונה הוא מה שמציע לנו הקומפיילר: נקרא לConstructor הדיפולטי:
|
|
זה יעבוד, אבל יש פה התנהגות מוזרה: אנחנו מאתחלים תחילה את כל השדות בערכים דיפולטים, ואחר כך בערכים האמיתיים. אולי ככה התרגלנו לעשות במחלקות, אבל משהו לא טוב כאן. במיוחד עבור מי שרוצה להשתמש בstruct דווקא משיקולי ביצועים, שהרי ככה הערכים מאותחלים פעמיים.
- אופציה שנייה היא להסיר את הConstructor הזה. ככה אי-אפשר לאתחל את הProperties האלה
- אופציה שלישית היא לעשות מימוש שהוא לא Auto-Property ואז לאתחל ישירות את השדות בערכים האמיתיים שלהם, אבל רק אתחול אחד
הייתי הולך על הפתרון השלישי, אבל כל אחד ומה שנראה לו.
המשך יום מובנה טוב