2010-11-12 9 views
17

NOTA: Prima di leggere o fornire una risposta, so di Enumerable.Distinct, chiedo sul supporto lingua specifica per questo metodo, non sul metodo stesso.Perché LINQ non include una parola chiave `distinct`?

Mi sono sempre chiesto il motivo per cui non v'è alcun distinct parola chiave nel C# LINQ set di parole chiave in modo che ho potuto scrivere:

var items = distinct from x in y 
      select x; 

o

var items = from x in y 
      select distinct x; 

Qualcuno sa il motivo per cui questo non è stato incluso o perché sarebbe una cattiva idea includerlo? Mi sembra semplicemente ingombrante che devo completare la query solo per chiamare Distinct(); una parola chiave distinct si sentirebbe più naturale.

NOTA: So che il metodo Distinct ha l'override per fornire un confronto se è necessario, ma una parola chiave che utilizza il confronto predefinito sarebbe ottima. Potrei anche immaginare una combinazione distinct by parola chiave in modo che un operatore di confronto potrebbe essere fornito in linea alla query.

+1

Vorrei che avessimo troppo. Sarebbe molto più leggibile, ed è ragionevolmente usato. –

+0

@qstarin: ho fatto la domanda perché ne avevo bisogno per la quinta volta in 2 giorni. –

+0

Forse dovremmo avviare un gruppo facebook "parola chiave distinta per C#". Ha ottenuto Betty White su SNL ... –

risposta

10

Charlie Calvert ha un blog post ("Using Distinct and Avoiding Lambdas") discutere la questione. Dalla cima del post:

  1. maggior parte degli operatori di query come Select(), Where() e GroupBy() prendere qualcosa chiamato un lambda come parametro.
  2. Lambda sono difficili da scrivere.
  3. Le espressioni di query sono state create in gran parte per consentire agli sviluppatori di utilizzare LINQ senza dover imparare la sintassi complessa associata a lambda.
  4. Alcuni operatori di query, come ad esempio Distinct(), non prendono lambda come parametri. Di conseguenza, sono facili da chiamare.
  5. Le espressioni di query non sono state pertanto create per operatori come Distinct() che non accettano lambda.

E inoltre, da più in basso nel post:

operatori di query sono chiamate a metodi. In altre parole, ci sono metodi nell'API LINQ chiamati Select(), Group(), Distinct(), ecc. Di solito non chiamiamo questi metodi direttamente perché prendono lambda come parametri, e molte persone trovano che lambda sia difficile da capire. Per aiutare gli sviluppatori ad evitare il complesso compito di scrivere lambda, il team ha inventato le espressioni di query, che sono uno "zucchero sintattico" che si trova in cima a lambda.

TL; DR: Non c'è distinct parola chiave per semplicità, dal momento che distinct non prende un'espressione lambda.

+2

Ottima risposta, grazie. Tutto ciò sembra fantastico, ma non si adatta a come le persone usano questa roba. Sarebbe estremamente utile e rende le cose molto più facili da leggere. Non credo che l'argomentazione avanzata da Charlie Calvert sia davvero così forte, specialmente dal momento che la parola chiave WAS è stata inclusa per VB. –

+6

"Di solito non chiamiamo questi metodi direttamente perché prendono lambda come parametri, e molti ** programmatori schifosi che non valgono il loro sale ** trovano che i lambda sono difficili da capire" - FTFY. – Juliet

+2

Totalmente d'accordo con entrambi. Lambdas non è così difficile, e sono stato inciampato da questo prima - "aspetta, quindi c'è un metodo' Distinct() 'ma nessuna parola chiave 'distinta'?" Ha poco senso per me. – Donut

14

In VB, c'è in realtà è.

Dim l = From x In {1, 2, 3, 2, 4, 2} Distinct Select x 

Non sospetto c'è stata qualche decisione attivo contro distinct per C#, è solo non è stato attuato.

+0

Ovviamente, non voglio dover scrivere tutto il mio LINQ in VB. :) –

+2

VB supporta anche 'Take' e' Skip' in formato query. –

+0

VB ha anche "Aggregate ... Into' in formato query? Questo esiste anche in C#? – Dario

5

Reword: distinct è un operatore set ... gli operatori di set non accettano lambda come parametri. Il team C# ha deciso di darti scorciatoie ai metodi che utilizzano lambda, come ad esempio Select() e Group(), perché sentivano che lambda poteva essere fonte di confusione per le persone appena agli inizi. .Distinct() non accetta un lambda, quindi è chiaro quando lo si chiama direttamente.

Una buona lettura sul tema:
http://blogs.msdn.com/b/charlie/archive/2006/11/19/linq-farm-group-and-distinct.aspx

+1

Questo spiega la differenza, ma continuo a non pensare che risponda alla domanda. 'in' non usa un lambda. È una comodità. L'argomento è difettoso, soprattutto quando si vede che VB ha ottenuto la parola chiave. Penso che la giustificazione sia debole - non è una critica alla tua risposta mentre stai trasmettendo le informazioni, ma ottieni il mio punto. –

+0

Ristrutturato. Hai ragione, la chiave è che è solo una comodità. Il team C# ha deciso che non era necessario per comodità su '.Distinct()' (Apparentemente la squadra VB non era d'accordo) –

+1

Penso che abbiano preso una decisione sbagliata per quanto riguarda il distinto. –