lambda come argomento predefinito

Stavo cercando un anwer da mettere in discussione Ottenere i prossimi N elementi da enumerable non ha trovato alcun soddisfacente e fermentato il mio. Quello che mi è venuto in mente è stato

IEnumerable Chunk(IEnumerable src, int n, Func<IEnumerable, T> action){ IEnumerable head; IEnumerable tail = src; while (tail.Any()) { head = tail.Take(n); tail = tail.Skip(n); yield return action(head); } } 

Quello che mi piacerebbe davvero, è che l’azione abbia un valore predefinito t=>t , ma non riesco a capire come renderlo un argomento predefinito. La firma IEnumerable Chunk(IEnumerable src, int n, Func<IEnumerable, T> action = t=>t) fornisce un errore di syntax.

La mia domanda è, come faccio a fare questo?

Suppongo che questo sia identico a Specificare una funzione lambda come argomento predefinito ma per C # invece di C ++

Come nota a margine, so che non fa alcuna differenza sintattica, ma sarebbe più facile da leggere se avessi cambiato T e R ?

I valori predefiniti devono essere costanti e l’unico valore costante per un delegato è un riferimento null .

Ti suggerisco di usare invece l’overloading. Nota che t => t non sarebbe comunque valido, a meno che tu non sappia che c’è una conversione da IEnumerable a T , che non vedo da nessuna parte.

A parte il problema di validità delle espressioni lambda, è ansible utilizzare l’operatore null coalescing:

 IEnumerable Chunk(IEnumerable src, int n, Func, T> action = null) { action = action ?? (t => t); ... } 

… ma sarebbe una sorta di abuso, e non si sarebbe in grado di dire se il null fosse effettivamente da un chiamante che pensava di passare un valore non nullo, e preferirebbe che alzassi ArgumentNullException .

EDIT: Inoltre, tieni presente che il tuo metodo è fondamentalmente problematico: l’iterazione dei blocchi valuta più volte la sequenza originale (una volta per chunk) per saltare la giusta quantità. Probabilmente sarebbe meglio scrivere un metodo che leggesse avidamente ogni pezzo prima di restituirlo. Abbiamo un metodo simile in MoreLINQ , chiamato Batch . Nota che Batch ha esattamente il sovraccarico qui menzionato – e in questo caso, t => t funziona, perché il sovraccarico ha meno parametri di tipo, quindi sappiamo che la conversione dell’id quadro è ok.

È lo stesso per C #: crea un sovraccarico.

 IEnumerable Chunk(IEnumerable src, int n){ return Chunk(src, n, t => t); }