Καλώς ορίσατε στο dotNETZone.gr - Σύνδεση | Εγγραφή | Βοήθεια
σε

 

Αρχική σελίδα Ιστολόγια Συζητήσεις Εκθέσεις Φωτογραφιών Αρχειοθήκες

Yield to my power !!!

Îåêßíçóå áðü ôï ìÝëïò anjelinio. Τελευταία δημοσίευση από το μέλος anjelinio στις 08-10-2007, 14:25. Υπάρχουν 2 απαντήσεις.
Ταξινόμηση Δημοσιεύσεων: Προηγούμενο Επόμενο
  •  08-10-2007, 13:32 35964

    Yield to my power !!!

    Καιρό τώρα, καθώς περνάμε αργά αλλά σταθερά απο 1.1 σε ... 3.5 ( culture shock το λένε αυτό ... ), πολύς κόσμος κολλάει στο ... yield.

    "Τυπικά", το yield είναι ένα keyword που παίζει απο καιρό, και "παραδίδει τον έλεγχο του execution flow στον caller".

    Προσπαθούσα λοιπόν να το εξηγήσω αυτό στα μικράκια μας, και έψαχνα ένα καλό παράδειγμα. Και νομίζω ότι την Παρασκευή .. το βρήκα:

            /// <summary>
            /// Will recursively scan a folder and all it's subfolders, returning all the contained files
           
    /// in a single IEnumerator<string> ...       
           
    /// <param name="basePath"></param>
           
    /// <returns></returns>
          
    /// </summary>
           
    static IEnumerator<string> ScanFolderTree(string basePath) {
    1            string[] fileNames = Directory.GetFiles(basePath);
    2            // First return each of the files ...
    3           
    foreach (string fileName in fileNames)
    4                yield return fileName;

    5            // then the subfolder files .. recursively !!! :D :D :D
    6           
    foreach (string folderName in Directory.GetDirectories(basePath)) {
    7                IEnumerator<string> subFolderFiles = ScanFolderTree(folderName);
    8                while(subFolderFiles.MoveNext())
    9                    yield return subFolderFiles.Current;
    10           
    }         

    11            yield break;
    12        }

    Η μικρή "απάτη" παραπάνω, γυρίζει ένα IEnumerator<string> που περιέχει όλα τα files που υπάρχουν σε ένα folder tree. Υπο κανονικές συνθήκες, χωρίς το yield keyword, αυτό δε θα μπορούσε να γίνει εύκολα.

    Η ... μαγεία αρχίζει στη γραμμή 4. Όσο το string[] έχει ακόμη items, κάθε yield θα γυρίζει το επόμενο item απο το array. Η "μαγκιά" τώρα με το yield. Όταν αυτό το foreach τελειώσει, η εκτέλεση θα συνεχίσει στην επόμενη γραμμή !

    Συνεχίζω λοιπόν, και παίρνω και τα folder names κάτω απο το basePath. Κι εδώ παίζει πλέον στην γραμμή 7 η recursive  - δε μπορώ να γράψω τη λέξη που σκέφτομαι - "μαγκιά" του όλου θέματος, και καλώ τη μέθοδο, με basePath, το εκάστοτε subFolder μου.

    Προσοχή τώρα ... εφ' όσον αυτό είναι recursive, και με παράμετρο το subFolder, θα γίνει το ίδιο πράγμα. Θα κάνει enumerate τα αρχεία, και μετά με τη σειρά του recursively και τα δικά του sub-folders Wink

    Έχοντας λοιπόν έναν IEnumerator<string> ως αποτέλεσμα του recursive call, μπορώ στις γραμμές 8-9 να τον κάνω enumerate, και να επιστρέφω ένα ένα τα αρχεία που μου επιστρέφει  ( μοιάζει με Tree traversal, εκεί που περνας απο όλα τα leaf nodes με ένα συγκεκριμένο τρόπο; ).

    Και τέλος λές κι ένα yield brake, για να σταματήσει κάποτε όλη αυτή η ιστορία - αλλιώς θα γυρίζει null για πάντα μόλις τελειώσουν όλα τα αρχεία !!!

    Όλα λοιπόν αυτά τα "μαγικά" δε θα μπορούσαν να γίνουν, χωρίς το yield keyword, το οποίο "παραδίδει τον έλεγχο του execution flow στον caller" και σου επιτρέπει να συνεχίσεις μετά στις γραμμές παρακάτω Smile

    Yield to it's power λοιπόν, και χρησιμοποιείστε το. Ανοίγει πόρτες μέχρι τώρα κλειστές μόλις το "πιάσεις" ...

    Καλό μας απόγευμα ...

    Angel
    O:]
  •  08-10-2007, 14:10 35966 σε απάντηση της 35964

    Απ: Yield to my power !!!

    Καλησπέρα φιλε Άγγελε,

    Μια χαρά το παράδειγμα που έδωσες... απλά μια μικρή αλλαγή...

    static IEnumerable<string> ScanFolderTree(string basePath)
    {
       string[] fileNames = Directory.GetFiles(basePath);
       // First return each of the files ...
       foreach (string fileName in fileNames)
          yield return fileName;
       // then the subfolder files .. recursively !!! :D :D :D
       foreach (string folderName in Directory.GetDirectories(basePath))
          foreach(string subFolderFile in ScanFolderTree(folderName))
             yield return subFolderFile;
    }

    Νομίζω... ότι τώρα είναι "λιγάκι" πιο καθαρό


    Palladinos Nick
    Software Engineer
    -----------------------
    The limits of my language mean the limits of my world. (Ludwig Wittgenstein)
  •  08-10-2007, 14:25 35967 σε απάντηση της 35966

    Απ: Yield to my power !!!

    Σαφώς

    Angel
    O:]
Προβολή Τροφοδοσίας RSS με μορφή XML
Με χρήση του Community Server (Commercial Edition), από την Telligent Systems