325. Covariance workaround

הכרנו בעבר (טיפים מספר 36-40) את המושגים של covariance וcontravariance.

ראינו שהFeatureים האלה קיימים רק מC# 4.0.

אפשר לחקות את ההתנהגות הזאת גם בC# 2.0 ומעלה בצורה הבאה:

אם אנחנו רוצים שפונקציה שלנו תוכל להתמודד למשל עם IEnumerable ועם IEnumerable<> של כל מה שיורש מShape, אז נוכל לעשות משהו כזה:

1
2
3
4
5
public void Draw<TShape>(IEnumerable<TShape> shapes)
where TShape : Shape
{
// ...
}

כעת נוכל לקרוא לה כך:

1
2
3
4
5
List<Shape> shapes = new List<Shape>();
List<Square> squares = new List<Square>();
Draw(shapes);
Draw(squares);

זה עובד בזכות הFeature האהוב עלי של הקומפיילר שיודע לזהות implicitly את הפרמטר הגנרי שאנחנו מעוניינים לשלוח לפונקציה. (ראו גם טיפ מספר 28)

כמובן, זה לא מאפשר לנו כל מה שמאפשר covariance, אבל זה פתרון אפשרי.


כמובן, אם אנחנו מתכנתים בC# 4.0, ניתן להשתמש בCovariance של IEnumerable ופשוט לכתוב כך:

1
2
3
4
public static void Draw(IEnumerable<Shape> shapes)
{
// ...
}

ואז זה יעבוד.

סוף שבוע קו-ואריאנטי טוב!

שתף