335. Collection{T} class

כולנו מכירים את הממשק ICollection אותו מממשים טיפוסים רבים בFramework, ביניהם List וT[].

המימושים נחמדים, אבל לפעמים אנחנו רוצים לבצע איזושהי פעולה בעת שינוי של האוסף. יש מספר דוגמאות, אחת מהן היא וואלידציה – אנחנו מעוניינים להכניס איבר לCollection רק אם הוא תקין.

עוד דוגמא היא שינוי האובייקט שנכנס לרשימה – למשל אם יש לנו אוסף של חיות ששייכות למישהו, אנחנו יכולים לשנות את הבעלים של החיה להיות הבעלים המתאימים.

דוגמא נוספת היא הקפצת אירוע – אנחנו מעוניינים להקפיץ אירוע כשהרשימה משתנה בתנאים מסוימים (למשל, כשנכנס איבר לא תקין, להקפיץ על כך אירוע)

אפשר לעטוף את List בICollection ולהוסיף לו את הפונקציונאליות שמעניינת אותנו, אבל יש דרך יותר פשוטה לבצע דבר כזה בFramework:

קיים הטיפוס Collection העוטף List, אבל בנוסף גם מאפשר לנו להתערב במה שקורה כאשר נוסף איבר, מסירים איבר, משתנה איבר במקום מסוים, או מרוקנים את האוסף:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class MyCollection<T> : Collection<T>
{
protected override void ClearItems()
{
// ...
}
protected override void InsertItem(int index, T item)
{
// ...
}
protected override void RemoveItem(int index)
{
// ...
}
protected override void SetItem(int index, T item)
{
// ...
}
}

במימושנו נוכל לקרוא לbase, ואז תקרה הפעולה הרגילה, אך נוכל להוסיף פונקציונאליות משלנו, למשל:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class Club : Collection<Person>
{
private readonly int mMaxPeopleAllowed;
public Club(int maxPeopleAllowed)
{
mMaxPeopleAllowed = maxPeopleAllowed;
}
protected override void InsertItem(int index, Person item)
{
if (item.Age < 21)
{
throw new TooYoungException("Entrance is allowed only for people that are at least 21.");
}
if (this.Count == mMaxPeopleAllowed)
{
throw new ClubFullException("The number of allowed people in the club is limited to " +
mMaxPeopleAllowed);
}
base.InsertItem(index, item);
}
}

סופ"ש אוספים טוב.

שתף