379. Default arguments values vs object initializer

הכרנו בעבר את הObject Initializer המאפשר לאתחל ערכים של המחלקה בצורה נוחה. (ראו גם טיפ מספר 87)

בהמשך הכרנו גם את הFeature של Default Value Arguments (הFeature של C# 4.0 – ראו גם טיפ מספר 243)

כעת יש לנו שתי דרכים עיקריות לאתחל מחלקה:

  • אופציה ראשונה – להעביר את כל הערכים בConstructor, ולסמן את הערכים שיש להם ערכים דיפולטיים עם Default argments
  • אופציה שניה – לאתחל את כל הProperties של המחלקה בעזרת Object Initializer (ולאתחל את יתר השדות בערכים הדיפולטיים שנקבע)

לדוגמה, את המחלקה הזאת ניתן לאתחל בשתי דרכים:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class Person
{
public Person()
{
IsMarried = false;
NumberOfChildren = 0;
}
public Person(string name, bool isMarried= false, int numberOfChildren = 0)
{
Name = name;
IsMarried = isMarried;
NumberOfChildren = numberOfChildren;
}
public string Name { get; set; }
public bool IsMarried { get; set; }
public int NumberOfChildren { get; set; }
}

ניתן לאתחל בשתי דרכים:

הדרך הראשונה:

1
Person person = new Person(name: "Yosi", isMarried: true);

הדרך השנייה:

1
2
3
4
5
Person person = new Person()
{
Name = "Yosi",
IsMarried = true,
};

נשווה בין שתי השיטות:

היתרון בשיטה הראשונה היא שהיא מאפשרת לנו שהFields של המחלקה יהיו readonly (ראו גם טיפ מספר 14), בנוסף היא יכולה לחייב אותנו לאתחל פרמטר מסוים.

החסרונות שלה הם הבאים:

  • נוכל לשים בתור Default argument value רק ערכים שהם Compile-time
  • בכל פעם שנשנה את הערכים הדיפולטיים, נצטרך לקמפל מחדש את כל הDLLים שמשתמשים במחלקה שלנו – זאת מאחר וDefault argument values נכתבים Hard-coded בתוך הקוד בזמן קימפול (ראו גם טיפ מספר 244)

היתרון של השיטה השנייה היא שנוכל לשים בתור Default argument value גם ערכים שהם לא Compile-time, ובמידה ונשנה ערך דיפולטי, זה לא יגרור קימפול מחדש של DLL שמשתמש במחלקה שלנו. החסרון הוא, כמובן, שהProperty הוא לא readonly (במידה ונרצה שהוא readonly), ושאנחנו לא יכולים לחייב את המשתמש לאתחל שדות מסוימים, אלא אם נקבל אותם בConstructor.

המשך יום דיפולטי שמאתחל אובייקטים טוב.

שתף