מדריך #C מתקדם – Generics: Constraints – התניות על פרמטרים גנריים
ניתן להגביל את הטיפוס שנהיה מוכנים לקבל כפרמטר גנרי באמצעות המילה השמורה where. בדרך-כלל נגביל את הטיפוס ל- class, struct או שנחייב אותו לממש ממשק (interface) מסוים.
הפונקציה בדוגמא הבאה, מקבלת 2 פרמטרים גנריים. הראשון חייב להיות struct היורש משני הממשקים IComparable, IFormattable. הפרמטר השני חייב להיות class היורש מהממשק ICloneable:
public void MethodWithConstrain<T, K>(T a, K b)
where T : struct, IComparable, IFormattable
where K : class, ICloneable
{
Console.WriteLine(a);
Console.WriteLine(b);
}
דוגמא נוספת – שימו לב ל- 11 ההעמסות של פונקצית Max של מחלקת Math:
בדרך-כלל, ניתן לחסוך מימושים שונים של אותה הפונקציה (בהעמסות שונות של סוגי טיפוסים) על-ידי שימוש במנגנון הג'נרי. כלומר, באמצעות Generics ,לדוגמא, נוכל ליצור פונקציה אחת שמקבלת טיפוס כלשהו שהוא בר-השוואה (שניתן להשוות בין ערכים שונים מאותו הטיפוס) ולחסוך את המימושים הנוספים המיותרים:
public static T Max<T>(T a, T b)
where T : IComparable
{
if (a.CompareTo(b) > 0)
return a;
return b;
}
פונקציה זו יכולה להשוות בין שני פריטים כלשהם, מכל class/struct קיים/עתידי כל עוד הוא עונה לקריטריון הבא: יורש מהממשק IComparable.
Console.WriteLine(Max<int>(3, 5));
Console.WriteLine(Max<double>(9.5, 3.6));
Console.WriteLine(Max<string>("Hi", "Bye"));
Console.WriteLine(Max<DateTime>(DateTime.Now,
new DateTime(2011, 2, 1)));
Console.WriteLine(Max<Person>(p1, p2));
(הטיפוס Person הוא דוגמא למחלקה שאנחנו יכולים ליצור בעצמנו, ליישם לה IComparable, ואז להפעיל עליה את הפונקציה הנ"ל).
הפלט:
באופן זה ניתן להגביל גם את הטיפוסים במחלקות (נחייב את הטיפוס לממש את IComparable):
class Point <T>
where T : IComparable
{
…
}
תגובות בפייסבוק