Καιρό τώρα, καθώς περνάμε αργά αλλά σταθερά απο 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

Έχοντας λοιπόν έναν IEnumerator<string> ως αποτέλεσμα του recursive call, μπορώ στις γραμμές 8-9 να τον κάνω enumerate, και να επιστρέφω ένα ένα τα αρχεία που μου επιστρέφει ( μοιάζει με Tree traversal, εκεί που περνας απο όλα τα leaf nodes με ένα συγκεκριμένο τρόπο; ).
Και τέλος λές κι ένα yield brake, για να σταματήσει κάποτε όλη αυτή η ιστορία -
αλλιώς θα γυρίζει null για πάντα μόλις τελειώσουν όλα τα αρχεία !!! Όλα λοιπόν αυτά τα "μαγικά" δε θα μπορούσαν να γίνουν, χωρίς το yield keyword, το οποίο "
παραδίδει τον έλεγχο του execution flow στον caller" και σου επιτρέπει να συνεχίσεις μετά στις γραμμές παρακάτω
Yield to it's power λοιπόν, και χρησιμοποιείστε το. Ανοίγει πόρτες μέχρι τώρα κλειστές μόλις το "πιάσεις" ... Καλό μας απόγευμα ...
Angel
O:]