149. MakeGenericMethod

ראינו איך אפשר להריץ מתודות על פי הMethodInfo שלהן.

מה אם המתודה שלנו גנרית?

למשל:

1
2
3
4
5
6
7
public static class SuperMethods
{
public static IEnumerable<T> ToArray<T>(T item)
{
return new T[] {item};
}
}

(ראו גם טיפים 26-27)

נוכל לנסות לעשות משהו כזה, כמו שעשינו עד עכשיו:

1
2
3
4
5
MethodInfo toArray =
typeof (SuperMethods).GetMethod("ToArray");
object array =
toArray.Invoke(null, new object[] {"The string"});

אלא שנקבל Exception כזה:

InvalidOperationException: Late bound operations cannot be performed on types or methods for which ContainsGenericParameters is true.

הסיבה היא די ברורה – המתודה לא יודעת מהו הפרמטר הגנרי שאנחנו רוצים לשלוח לפונקציה. כדי לפתור זאת, נוכל להשתמש במתודה דומה למתודה MakeGenericType (טיפ מספר 140). שמה הוא MakeGenericMethod. למתודה זו אנחנו מעבירים את הפרמטרים הגנריים שאנחנו מעוניינים לשלוח לפונקציה, והיא מחזירה לנו MethodInfo המתאר את הפונקציה עם הפרמטר הגנרי המוזרק:

1
2
3
4
5
6
7
8
9
MethodInfo toArray =
typeof (SuperMethods).GetMethod("ToArray");
MethodInfo stringToArray =
toArray.MakeGenericMethod(typeof (string));
object array =
stringToArray.Invoke(null, new object[] { "The string"}); // new []{ "The string" }
// Like object array = SuperMethods.ToArray<string>("The string");

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

המשך יום גנרי משתקף לטובה

שתף