porque nos da algo que es útil. Considere lo siguiente:
var countSameName = from p in PersonInfoStore
group p.Id by new {p.FirstName, p.SecondName} into grp
select new{grp.Key.FirstName, grp.Key.SecondName, grp.Count()};
Las obras porque la implementación de Equals()
y GetHashCode()
para los tipos anónimos funciona sobre la base de la igualdad de campo por campo.
- Esto significa lo anterior estará más cerca de la misma consulta cuando se ejecuta contra al
PersonInfoStore
que no se LINQ a objetos. (Todavía no es lo mismo, coincidirá con lo que hará una fuente XML, pero no con lo que resultaría en la mayoría de las intercalaciones de bases de datos).
- Esto significa que no tenemos que definir
IEqualityComparer
para cada llamada a GroupBy
que agruparía muy difícilmente con objetos anónimos - es posible pero no es fácil definir un IEqualityComparer para objetos anónimos - y lejos del significado más natural .
- Sobre todo, no causa problemas en la mayoría de los casos.
El tercer punto vale la pena examinar.
Cuando definimos un tipo de valor, es natural que quieren un concepto basado en el valor de la igualdad. Si bien es posible que tengamos una idea diferente de la igualdad basada en el valor que la predeterminada, como la coincidencia de un campo dado con las mayúsculas y minúsculas, el valor predeterminado es lógico (si el rendimiento es deficiente y no funciona bien en un caso *). (Además, la igualdad de referencia no tiene sentido en este caso).
Cuando definimos un tipo de referencia, que puede o no querer un concepto basado en el valor de la igualdad. El valor predeterminado nos da igualdad de referencia, pero podemos cambiar eso fácilmente. Si hacemos cambiarlo, podemos cambiarlo por sólo Equals
y GetHashCode
o para ellos y también ==
.
Cuando definimos un tipo anónimo, oh espera, no nos definimos, que es lo que significa anónimos! La mayoría de los escenarios en los que nos preocupamos por la igualdad de referencia ya no existen. Si vamos a tener un objeto alrededor el tiempo suficiente para luego preguntarnos si es el mismo que otro, probablemente no estemos lidiando con un objeto anónimo. Los casos en los que nos importa la igualdad basada en el valor surgen mucho. Muy a menudo con LINQ (GroupBy
como vimos más arriba, sino también Distinct
, Union
, GroupJoin
, Intersect
, SequenceEqual
, ToDictionary
y ToLookup
) y, a menudo con otros usos (que no es como que no estábamos haciendo las cosas LINQ hace por nosotros con enumerables en 2.0 y hasta cierto punto antes de eso, cualquiera que codifique en 2.0 habría escrito la mitad de los métodos en Enumerable
ellos mismos).
En general, ganamos mucho gracias a la igualdad de las clases anónimas.
En la posibilidad de que alguien realmente quiera igualdad de referencia, ==
usando la igualdad de referencia significa que todavía tienen eso, así que no perdemos nada. Es el camino a seguir.
* La implementación predeterminada de Equals()
y GetHashCode()
tiene una optimización que permite usar una coincidencia binaria en los casos en que sea seguro hacerlo. Desafortunadamente, hay un error que a veces hace que algunos casos se identifiquen erróneamente como seguros para este enfoque más rápido cuando no lo están (o al menos solían hacerlo, tal vez lo arreglaron). Un caso común es que si tiene un campo decimal
, en una estructura, entonces considerará algunas instancias con campos equivalentes como desiguales.
Esta es una de las pocas publicaciones en SO que tiene 3 o más respuestas donde el representante promedio. de responder chicos ha terminado ** 95k **, desde mayo-23-2017. – dotNET