שאלה דחופה בC# - אולי תוכלו להסביר?

תכנות זה עולם

משתמש רשום
יש לי מקרה שאני צריכה לטפל בו שזהה בדיוק לשאלה הבאה:
קישור לשאלה מstack overflow
הסתכלתי על הפתרון הראשון והוא נראה לי מצוין אבל אני לא מצליחה להבין בו שתי דברים:
דבר ראשון - מה המשמעות של השימוש בyield
ודבר שני - למה הוא השתמש בפונקצית הרחבה ומה התועלות שלה?
תכלס אני לא מצליחה לממש את זה אצלי בקוד.
אשמח מאד לעזרה!!!
 

גזעי

משתמש מקצוען
הנדסת תוכנה
D I G I T A L
IEnumarable<T> הוא ממשק של מספר פונקציות שעובדות ביחד כדי להחזיר "רשימה" של ערכים, והוא עובד עם foreach במובנה.
yield זה בעצם כמו return רגיל, אבל הוא לא יוצא מהפונקציה, הוא מחזיר את הערך "הבא" ברשימה (אחת מהפונקציות של הממשק זה ()next)
הנה דוגמה למימוש של פונקציה שמחזירה אוסף (collection) של הערכים 0 עד 9,
C#:
public static IEnumerable<int> getVals()
{

    int[] arr = new int[10];

    for (int i = 0; i < 10; i++)

        arr[i] = i;

    return arr;

}

והנה דוגמה באמצעות שימוש בyield
C#:
public static IEnumerable<int> getVals()
{
    for (int i = 0; i < 10; i++)
        yield return i;
}

עכשיו מה ההבדל בין שני הפונקציות?
הראשונה צריכה לעבור על כל המערך ולהקצות אותו לפני שהיא מחזירה ערך,
הפונקציה השניה צריכה בכל פעם שקוראים לפונקציה next (זה נעשה מאחורי הקלעים של C#) רק להחזיר את הערך הבא, אם יש לך אפילו 100000000 ערכים ואת רק צריכה את ה-10 הבאים, אז את לא צריכה לחכות עד לסיום ריצת הפונקציה, אלא רק עד ה-10 ריצות הבאות של הyield.


לגבי המתודת הרחבה (extension method), זה סתם יותר קריא, זה סוג של סוכר סינטטי לתחביר, אין הבדל מהותי באמת.
 

תהילה ר

משתמש פעיל
IEnumarable<T> הוא ממשק של מספר פונקציות שעובדות ביחד כדי להחזיר "רשימה" של ערכים, והוא עובד עם foreach במובנה.
yield זה בעצם כמו return רגיל, אבל הוא לא יוצא מהפונקציה, הוא מחזיר את הערך "הבא" ברשימה (אחת מהפונקציות של הממשק זה ()next)
הנה דוגמה למימוש של פונקציה שמחזירה אוסף (collection) של הערכים 0 עד 9,
C#:
public static IEnumerable<int> getVals()
{

    int[] arr = new int[10];

    for (int i = 0; i < 10; i++)

        arr[i] = i;

    return arr;

}

והנה דוגמה באמצעות שימוש בyield
C#:
public static IEnumerable<int> getVals()
{
    for (int i = 0; i < 10; i++)
        yield return i;
}

עכשיו מה ההבדל בין שני הפונקציות?
הראשונה צריכה לעבור על כל המערך ולהקצות אותו לפני שהיא מחזירה ערך,
הפונקציה השניה צריכה בכל פעם שקוראים לפונקציה next (זה נעשה מאחורי הקלעים של C#) רק להחזיר את הערך הבא, אם יש לך אפילו 100000000 ערכים ואת רק צריכה את ה-10 הבאים, אז את לא צריכה לחכות עד לסיום ריצת הפונקציה, אלא רק עד ה-10 ריצות הבאות של הyield.


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

גזעי

משתמש מקצוען
הנדסת תוכנה
D I G I T A L
התוצאה תהיה אותו דבר בשתי האופציות?
כן ולא, התוצאה תהיה אותו דבר, אבל הפונקציה הראשונה צריכה להקצות את כל המידע בזיכרון, בעוד שהפונקציה השניה מחזירה on the run (תוך כדי ריצה) את הערכים.

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

תכנות זה עולם

משתמש רשום
תכלס בדוגמה השימוש בזה הוא כך:
root.Descendants().Where(node => node.Key == SomeSpecialKey)
מה מחזירה השורה הזאת?
אני מנסה להציב אוביקט מהסוג המוחזר וזה שולח הודעת שגיאה שהוא לא יכול להמיר סוג של
WhereEnumerableIterator
לסוג המוחזר
 

סמרקט

מהמשתמשים המובילים!
הנדסת תוכנה
D I G I T A L
תוכלי לרשום כאן את הקוד שמחזיר לך שגיאה?
אולי זה מה שחסר?
C#:
root.Descendants().Where(node => node.Key == SomeSpecialKey).First()
 

תכנות זה עולם

משתמש רשום
אכן הפתרון היה להוסיף FirstOrDefault
לגבי:
לגבי המתודת הרחבה (extension method), זה סתם יותר קריא, זה סוג של סוכר סינטטי לתחביר, אין הבדל מהותי באמת.
איך אני יכולה לכתוב את הפונקציה כפונקציה רגילה?
ניסיתי בהרבה צורות ולא הצלחתי. אפשר דוגמה למקרה הנוכחי?
 

גזעי

משתמש מקצוען
הנדסת תוכנה
D I G I T A L
אכן הפתרון היה להוסיף FirstOrDefault
לגבי:

איך אני יכולה לכתוב את הפונקציה כפונקציה רגילה?
ניסיתי בהרבה צורות ולא הצלחתי. אפשר דוגמה למקרה הנוכחי?
בLINQ אי אפשר בתור פונקציה רגילה, אפשר סתם ליצור פונקציה שמקבלת ENUMERABLE ומחזירה ENUMERABLE
 

אולי מעניין אותך גם...

הפרק היומי

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


תהילים פרק קכג

א שִׁיר הַמַּעֲלוֹת אֵלֶיךָ נָשָׂאתִי אֶת עֵינַי הַיֹּשְׁבִי בַּשָּׁמָיִם:ב הִנֵּה כְעֵינֵי עֲבָדִים אֶל יַד אֲדוֹנֵיהֶם כְּעֵינֵי שִׁפְחָה אֶל יַד גְּבִרְתָּהּ כֵּן עֵינֵינוּ אֶל יְהוָה אֱלֹהֵינוּ עַד שֶׁיְּחָנֵּנוּ:ג חָנֵּנוּ יְהוָה חָנֵּנוּ כִּי רַב שָׂבַעְנוּ בוּז:ד רַבַּת שָׂבְעָה לָּהּ נַפְשֵׁנוּ הַלַּעַג הַשַּׁאֲנַנִּים הַבּוּז לִגְאֵיוֹנִים:
נקרא  18  פעמים

לוח מודעות

למעלה