138. Obtaining the type of a declared variable

אתמול הכרנו את הפונקציה GetType המאפשרת לנו להשיג את הType האמיתי של instance של אובייקט שיש לנו.

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

לדוגמה:

כתבנו פונקציה כזו:

1
2
3
4
public static Type GetVariableType(object value)
{
return value.GetType();
}

עכשיו אנחנו קוראים לה ככה:

1
2
3
IList myList = new List<string>();
Type myListType = GetVariableType(myList);
// typeof(List<string>)

אלא שהעברנו לפונקציה משתנה מסוג IList, והיינו רוצים לדעת מה הסוג של המשתנה שהועבר לפונקציה… (כלומר מאיזה טיפוס המשתמש בפונקציה שלנו ראה אותו)

נוכל לפתור זאת בצורה הבאה:

נהפוך את המתודה לגנרית:

1
2
3
4
public static Type GetVariableType<T>(T value)
{
return value.GetType();
}

ובמקום להחזיר את GetType של הvalue, נחזיר את הסוג של T:

1
2
3
4
public static Type GetVariableType<T>(T value)
{
return typeof (T);
}

אם עכשיו נבצע את השורות שראינו מעלה נקבל באמת הטיפוס שציפינו לקבל:

1
2
IList myList = new List<string>();
Type myListType = GetVariableType(myList); // typeof(IList)

מה סוד הקסם?

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

(טיפ מספר 28, וטיפ מספר 69)

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

עכשיו נוכל לכתוב כל מיני דברים מצחיקים כאלה:

1
2
3
4
5
6
7
8
public static bool IsTypeTooExplicit<T>(T value)
{
Type givenType = typeof(T);
// Prefer interfaces. (See also tip #81)
return (!givenType.IsInterface &&
givenType.GetInterfaces().Any());
}

המשך יום טיפוסי טוב

שתף