100. Multiple interface type

ובכן היום זה הטיפ היומי ה100,

לכבודו החלטתי לתת טיפ שהוא לא קשור לLINQ, אבל משהו נחמד שנראה לי מגניב מספיק כדי להיות בטיפ ה100.

נניח שיש לנו פונקציה שרוצה לקבל טיפוס שממש שני ממשקים. נקשה ונאמר שגם אין ממשק שיורש משני הממשקים.

1
2
3
4
5
6
7
8
9
public interface IShape
{
int NumberOfEdges { get; }
}
public interface IColored
{
Color Color { get; }
}

הדרך הקלאסית לעשות דבר כזה היא משהו כזה:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public static void MyMethod(IShape shape)
{
IColored colored = shape as IColored;
if (colored == null)
{
throw new ArgumentNullException
("shape",
"Expected a colored type");
}
else
{
Console.WriteLine("Number Of Edges: {0}, Color: {1}",
shape.NumberOfEdges,
colored.Color);
}
}

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

עם מספיק יצירתיות, אפשר לחשוב על הפתרון הזה:

1
2
3
4
5
6
7
public static void MyMethod<TColoredShape>(TColoredShape shape)
where TColoredShape : IColored, IShape
{
Console.WriteLine("Number Of Edges: {0}, Color: {1}",
shape.NumberOfEdges,
shape.Color);
}

ואז נוכל לקרוא למתודה פשוט כך:

נניח שיש לנו טיפוסים כאלה:

1
2
3
4
5
6
7
8
9
public class Triangle : IShape
{
// ...
}
public class ColoredTriangle : IShape, IColored
{
// ..
}

אז נוכל לקרוא למתודה ככה:

1
2
3
4
ColoredTriangle coloredTriangle =
new ColoredTriangle();
MyMethod(coloredTriangle);

אבל לא ככה:

1
2
3
Triangle triangle = new Triangle();
MyMethod(triangle);

מניב את שגיאת הקימפול

The type ‘Triangle’ cannot be used as type parameter ‘TColoredShape’ in the generic type or method ‘MyMethod(TColoredShape)’. There is no implicit reference conversion from ‘Triangle’ to ‘IColored’.

סופ"ש שאילתא מובנית שפה טוב

שתף