154. The Difference between First and Single

לפעמים יש לנו איזשהו IEnumerable ואנחנו מעוניינים לגשת לאיבר הראשון שלו.

לפני C# 3.0, הדרך לעשות זאת הייתה די זוועתית. אני זוכר שכתבתי שורות כאלה פעם:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
IEnumerable<string> strings =
new string[]
{
"A new hope",
"The empire strikes back",
"The return of the Jedi"
};
IEnumerator<string> stringsEnumerator =
strings.GetEnumerator();
string first = null;
if (stringsEnumerator.MoveNext())
{
first = stringsEnumerator.Current; // A new hope
}

יש פה די הרבה קוד בשביל בסה"כ לגשת לאיבר הראשון. יש פה גם כמה בעיות. מה אם האוסף ריק?

בLINQ הוסיפו לנו ארבע Extension Methods שעושות לנו את החיים טיפה יותר קלים.

המתודה הראשונה היא First:

1
string first = strings.First();

היא מחזירה לנו את האיבר הראשון באוסף. מה אם אין כזה? היא תזרוק לנו Exception. איך נוכל למנוע אותו?

באמצעות המתודה Any:

1
2
3
4
5
6
string first = null; // Put your default here :)
if (strings.Any())
{
first = strings.First();
}

(ראו גם טיפ מספר 15)

או באמצעות אחותה המתודה ששמה FirstOrDefault המחזירה לנו את האיבר הראשון באוסף או את default(T), במידה והאוסף ריק (כאשר T הטיפוס של אוסף), ראו גם טיפ מספר 32.

1
string first = strings.FirstOrDefault();

יש לזה שני חסרונות על השיטה הקודמת: הראשונה היא שאנחנו לא יכולים לקבוע מה יהיה הערך הדיפולטי (במידה ולא היו איברים ברשימה). החסרון השני הוא שאנחנו לא נדע אם נבחר האיבר הראשון או האיבר הדיפולטי (אם למשל נעבוד עם טיפוסים שהם Value types זה יכול לשנות לנו, כי אם האוסף יהיה למשל מסוג int אנחנו יכולים לקבל 0, ויכול להיות שזה הראשון, ולאו בהכרח הדיפולטי)


בנוסף, קיימות שתי פונקציות בעלות שמות דומים והם Single וSingleOrDefault. מה ההבדל ביניהן לשתי הפונקציות שכבר ראינו?

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

הפונקציה Single תזרוק לנו Exception אם אין לנו איבר יחיד באוסף (כלומר יש לנו 0 איברים או יותר מ1)

הפונקציה SingleOrDefault תזרוק לנו Exception אם יש לנו יותר מאיבר אחד ברשימה, אבל אם יש לנו 0, היא תחזיר לנו את הדיפולט.

סופ"ש נעים

שתף