כולנו מכירים את הממשק 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>
{
protectedoverridevoidClearItems()
{
// ...
}
protectedoverridevoidInsertItem(int index, T item)
{
// ...
}
protectedoverridevoidRemoveItem(int index)
{
// ...
}
protectedoverridevoidSetItem(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>
{
privatereadonlyint mMaxPeopleAllowed;
publicClub(int maxPeopleAllowed)
{
mMaxPeopleAllowed = maxPeopleAllowed;
}
protectedoverridevoidInsertItem(int index, Person item)
{
if (item.Age < 21)
{
thrownew TooYoungException("Entrance is allowed only for people that are at least 21.");
}
if (this.Count == mMaxPeopleAllowed)
{
thrownew ClubFullException("The number of allowed people in the club is limited to " +