2010-11-12 10 views
17

NOTA: Antes de leer o proporcionar una respuesta, sé acerca de Enumerable.Distinct, estoy preguntando sobre el soporte de idioma específico para ese método, no sobre el método en sí.¿Por qué LINQ no incluye una palabra clave `distinct`?

Siempre me he preguntado por qué no hay distinct palabra clave en el C# palabra clave LINQ configurar para que yo pudiera escribir:

var items = distinct from x in y 
      select x; 

o

var items = from x in y 
      select distinct x; 

Alguien sabe por qué esto no se incluyó o por qué sería una mala idea incluirlo? Me resulta engorroso que tengo que envolver la consulta solo para llamar al Distinct(); una palabra clave distinct se sentiría más natural.

NOTA: Sé que el método Distinct tiene anulaciones para proporcionar un comparador si es necesario, pero una palabra clave que use el comparador predeterminado sería genial. Incluso podría imaginar una combinación de palabras clave distinct by para que un operador de comparación pueda proporcionarse en línea a la consulta.

+1

Me gustaría que también lo tenía. Sería mucho más fácil de leer, y es razonablemente utilizado. –

+0

@qstarin: Formulé la pregunta porque la necesitaba por quinta vez en 2 días. –

+0

Quizás deberíamos comenzar un grupo de palabras clave "distinto para C#". Obtuve a Betty White en SNL ... –

Respuesta

10

Charlie Calvert tiene un blog post ("Using Distinct and Avoiding Lambdas") discutiendo el problema. Desde la parte superior del poste:

  1. La mayoría de los operadores de consulta tales como Select(), Where() y GroupBy() toman algo llamado lambda como parámetro.
  2. Las lambdas son difíciles de escribir.
  3. Las expresiones de consulta se crearon en gran parte para permitir a los desarrolladores utilizar LINQ sin tener que aprender la sintaxis compleja asociada con lambdas.
  4. Algunos operadores de consulta, como Distinct(), no toman lambdas como parámetros. Como resultado, son fáciles de llamar.
  5. Por lo tanto, las expresiones de consulta no se crearon para operadores como Distinct() que no toman lambdas.

Y también, desde más abajo en el mensaje:

operadores de consulta son las llamadas a métodos. En otras palabras, hay métodos en la API LINQ llamados Select(), Group(), Distinct(), etc. No solemos llamar a estos métodos directamente porque toman lambdas como parámetros, y muchas personas encuentran que las lambdas son difíciles de entender. Para ayudar a los desarrolladores a evitar la compleja tarea de escribir lambdas, el equipo inventó expresiones de consulta, que son un "azúcar sintáctico" que se sienta encima de las lambdas.

TL; DR: No hay distinct palabra clave por razones de simplicidad, ya que distinct no toma una expresión lambda.

+2

Excelente respuesta, gracias. Todo eso suena genial, pero no encaja con CÓMO la gente usa esto. Sería extremadamente útil y facilitaría la lectura de las cosas. No creo que el argumento presentado por Charlie Calvert sea realmente tan fuerte, especialmente desde que se incluyó la palabra clave WAS para VB. –

+6

"No solemos llamar a estos métodos directamente porque toman lambdas como parámetros, y muchos ** pésimos programadores que no valen la pena ** encuentran que las lambdas son difíciles de entender" - FTFY. – Juliet

+2

Totalmente de acuerdo con ambos. Lambdas no es tan difícil, y me he tropezado con esto antes - "espera, ¿entonces hay un método' Distinct() 'pero no' distinct'? " Tiene poco sentido para mí – Donut

14

En VB, en realidad es.

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

No sospecho que ha habido alguna decisión activa contra distinct para C#, es sólo no se ha implementado.

+0

Por supuesto, no quiero tener que escribir todo mi LINQ en VB. :) –

+2

VB también admite 'Take' y' Skip' en formato de consulta. –

+0

VB también tiene 'Aggregate ... Into' en formato de consulta? ¿Esto también existe en C#? – Dario

5

Reword: distinct es un operador establecido ... los operadores set no toman lambdas como parámetros. El equipo de C# decidió darle accesos directos a los métodos que toman lambdas, como Select() y Group(), porque sentían que las lambdas pueden ser confusas para las personas que recién comienzan. .Distinct() no toma una lambda, por lo que es claro cuando lo llamas directamente.

Una buena lectura sobre el tema:
http://blogs.msdn.com/b/charlie/archive/2006/11/19/linq-farm-group-and-distinct.aspx

+1

Eso explica la distinción, pero todavía no creo que responda la pregunta. 'in' no usa una lambda. Es una conveniencia. El argumento es defectuoso, especialmente al ver que VB obtuvo la palabra clave. Creo que la justificación es débil; eso no es una crítica a tu respuesta cuando transmites la información, pero entiendes mi punto. –

+0

Reformulado. Tienes razón, la clave es que es solo una conveniencia. El equipo de C# decidió que no había necesidad de una conveniencia en '.Distinct()' (Aparentemente el equipo de VB no estuvo de acuerdo) –

+1

Creo que tomaron una mala decisión con respecto a las distintas. –

Cuestiones relacionadas