88. Object initializer and calling base

נניח שיש לנו מחלקת אב ומחלקת בת שיורשת ממנה.

נניח בנוסף שהמחלקת אב צריכה לקבל מאיזושהי סיבה אובייקט בConstructor שלה, למשל:

1
2
3
4
5
6
public abstract class Animal
{
protected Animal(IFoodProvider provider)
{
}
}

ונניח עוד הנחות נוקשות, שאין Constructor מתאים שמאתחל את כל הProperties החשובים לנו באובייקט, למשל

1
2
3
4
5
6
public class Dog : Animal
{
public Dog() : base(new BoneProvider())
{
}
}

ולBoneProvider יש רק Constructor דיפולטי, או שאין לו Constructor שממלא את כל השדות שחשובים לנו.

כדי למלא את הProperties האלה בC# 2.0 היינו צריכים ליצור מתודה סטטית:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class Dog : Animal
{
public Dog() : base(GetBoneProvider())
{
}
private static IFoodProvider GetBoneProvider()
{
BoneProvider provider = new BoneProvider();
provider.AllowedBonesPerDay = 3;
provider.AvailableBones = 100;
return provider;
}
}

בC# 3.0 נוכל לחסוך ולהשתמש בObject Initializer כדי להעביר את הפרמטרים מעלה בצורה הבאה:

1
2
3
4
5
6
7
8
9
10
11
public class Dog : Animal
{
public Dog() :
base(new BoneProvider
{
AllowedBonesPerDay = 3,
AvailableBones = 100
})
{
}
}

שימו לב ששימוש זה חוסך לנו מתודה, אבל עשוי לפגוע בקריאות, לכן כדאי לשקול זאת.

בנוסף, פתרון זה טוב רק במידה וכל האתחולים נעשים דרך Properties.

אם קיים אתחול באמצעות מתודה (למשל OpenConnection()), נצטרך לחזור לפתרון של המתודה הסטטית.

המשך שבוע השלמות טוב

שתף