לפני Framework 2.0, היה ממשק בשם IEnumerable. אז לא היו טיפוסים גנריים, ולכן לא ניתן לדעת מהו הטיפוס הספציפי של האובייקטים באוסף זה.
בFramework 2.0 נוספו טיפוסים גנריים, ונוסף גם הממשק IEnumerable
לצרכי תאימות לאחור ושיקולים נוספים (טיפ מספר 150 למשל), רוב הטיפוסים בFramework שממשים IEnumerable
אלא, שלמרבה הצער, לא ניתן להשתמש ברוב הפונקציות של LINQ (כולל הQuery syntax) על הטיפוס IEnumerable, אלא רק על הגרסה הגנרית שלו.
דבר זה כואב מאוד למי שיוצא לו לעבוד עם חלקים מהFramework שהגיחו בFramework 1.0 ולא שודרגו מאז, לפחות מבחינת הAPI, ביניהם ADO.net (עבודה עםDataSet/DataTableים) וWindows Forms.
קיימים הרבה מאוד טיפוסים מתקופה זו שמממשים IEnumerable ולא IEnumerable
עם זאת, היוצרים של LINQ היו מספיק נחמדים בשביל לחשוב על פתרון גם למי שנאלץ להשתמש בטיפוסים אלה:
קיימות שתי Extension Methods של IEnumerable המסייעות לנו בעניינים אלה:
הראשונה היא Cast המאפשרת לנו להמיר את הIEnumerable שלנו לIEnumerable
|
|
מה שהפונקציה הזו עושה היא רצה על כל האיברים של האוסף המקורי, ויוצרת אוסף חדש ע"י הסבה לטיפוס שציינו.
כמובן, כפי שבוודאי יכולתם לנחש, פונקציה זו היא Lazy (כמו כל דבר בLINQ), ולכן גם אם האוסף המקורי שלנו משתנה, האוסף שנוצר ממנו יושפע מכך. (ההסבות תתבצענה רק כאשר נקרא לפונקציה MoveNext של הEnumerator, או לחלופין כשנרוץ על האוסף)
נוכל להשתמש בפונקציה זו גם לצרכים אחרים. נניח שאנחנו עובדים בFramework 3.5, וקיימת פונקציה שמצפה לקבל IEnumerable<Shape>, אבל יש לנו IEnumerable<Circle>. לא נוכל להעביר אוסף זה ישירות (ראו טיפים 36-40), אבל נוכל להשתמש בCast כדי לבצע את המשימה:
|
|
בנוסף לפונקציה Cast, קיימת גם הפונקציה OfType. פונקציה זו דומה לCast, אלא שהיא מסננת עבורנו רק את האיברים שהם מהטיפוס הגנרי שנעביר לה (בניגוד לCast שזורקת Exception ברגע שהיא לא מצליחה להסב לטיפוס הגנרי):
|
|
היא שימושית גם עבור סינונים כללים, למשל הנה דוגמה הפוכה לדוגמה שרשמתי למעלה: נניח שיש לנו אוסף של צורות, ואנחנו מעוניינים לסנן משם את כל המעגלים. נוכל לעשות זאת כך:
|
|
חג פסח ב’ שמח!