2010-09-23 37 views
14

considerare questo:IEnumerable <string> a stringa

string test = ""; 
somestring.ToList().Take(50).Select(
    delegate(char x) 
    { 
     test += x; 
     return x; 
    } 
); 

ora perché prova è vuota dopo? non mi interessa il ritorno di quello che effettivamente conosco IEnumerable.

in qualsiasi modo se questo è tutto sembra un pasticcio, allora come posso convertire IEnumerable<char> in stringa?

grazie in anticipo ..

risposta

21

Perché non hai esegue la query. Linq è pigro. Verrà eseguito quando lo si fa foreach o ToList/ToArray/ToDictionary.

e ho consigli per farlo in quel modo

string test = new string(somestring.Take(50).ToArray()); 

o anche utilizzando

string test = somestring.Substring(0, 50); 

Più su quello. Select ha lo scopo di applicare una sorta di trasformazione a ogni elemento in sequenza. Questa operazione è nota anche come map. Se vuoi produrre un singolo elemento dalla sequenza, è Aggregate, alias reduce. Non è pigro, costringe all'esecuzione di query.

+0

'Remove'? Penso che tu intenda "Sottostringa"? – Timwi

+0

@Greg Linq è un framework dichiarativo. questo a volte è qualcosa di sorprendente per gli sviluppatori di mentalità imperativa. – Andrey

+0

Questo non verrà compilato se 'somestring' è di tipo' IEnumberable '. La classe stringa non ha un costruttore sovraccaricato che accetta un array di stringhe. –

2

Poiché Select è pigro, la funzione passata verrà valutata solo dopo aver utilizzato il risultato di Seleziona.

In genere è una cattiva idea utilizzare le funzioni con effetti collaterali con Seleziona. Probabilmente dovresti usare foreach invece.

In questo caso particolare, è possibile utilizzare solo il metodo String.Join.

3

Select restituisce un IEnumerable<char> ma non lo si enumera nel codice in modo che il delegato non venga eseguito. Se lo cambi in:

string test = ""; 
somestring.Take(50).Select(
    delegate(char x) 
    { 
     test += x; 
     return x; 
    } 
).ToList(); 
3

Perché hai solo dichiarato la sequenza, ma non l'hai mai eseguita. Se hai aggiunto un altro .ToList() alla fine, quindi test avrebbe i caratteri in esso.

Tuttavia, raccomando fortemente questa pratica. Si sta utilizzando la valutazione di una sequenza su causa effetti collaterali. Hai già scoperto che i risultati sono confusi. Se davvero si vuole solo i primi 50 elementi di una sequenza, basta usare Take sola:

var partSequence = fullSequence.Take(50); 

vostro sopra esempio potrebbe essere scritto qualcosa di simile:

var partString = new string(someString.Take(50).ToArray()); 

ma sono sicuro che sei a conoscenza di string.Substring() per questo scopo.

14

(Altri hanno spiegato perché non funziona.)

La tua domanda non del tutto ha senso in questo momento - non è chiaro se si è in realtà che fare con un IEnumerable<char> o un IEnumerable<string>. (Il testo suggerisce IEnumerable<string>; il codice suggerisce IEnumerable<char>). Se è un IEnumerable<string> e si utilizza .NET 4, è davvero facile:

string combined = string.Join("", list.Take(50)); 

Se si sta utilizzando .NET 3.5, è ancora abbastanza facile:

string combined = string.Join("", list.Take(50).ToArray()); 

usare Ovviamente qualcosa come " , "se vuoi un delimitatore tra le corde.

Se hai a che fare con un generale IEnumerable<char> quindi utilizzare

string combined = new string(chars.Take(50).ToArray()); 

Se sei realtà che fare con una stringa per cominciare, utilizzare Substring :)

+1

Sì, ma penso che si stia chiedendo perché il suo codice non ha funzionato. – Timwi

+0

itera su stringa, vedi 'delegate (char x)'. Non penso che sia efficiente fare stringhe.Entrare su ienumerable di caratteri. – Andrey

+0

@Andrey: stavo basando la risposta sull'affermazione che sta cercando di concatenare un 'IEnumerable ', non un 'IEnumerable ' ... in pratica la domanda è rotta al momento. Ho modificato per indicarlo. –

Problemi correlati