Convenciones de nomenclatura de métodos de C #: ToSomething vs.AsSomething

82

Mientras escribía algunos métodos de extensión para mis objetos de lógica empresarial, me planteé la cuestión de cambiar el nombre de los métodos de conversión. someObject.ToAnotherObject()iría bien con el ampliamente utilizado object.ToString().

Sin embargo, LINQ, por ejemplo, mezcla ambas variantes y no puedo encontrar una diferencia entre ellas. ToDictionary(), ToList(), AsParallel(), AsQueryable(), ...

¿Cuáles son las diferencias entre estas dos convenciones de nomenclatura y qué debo saber para decidir si usarlo para mis propias clases?

Physikbuddha
fuente

Respuestas:

91

ToDictionaryy ToListtienen el prefijo Toporque no necesariamente preservan la identidad estructural de la colección original o sus propiedades.

  • Transformar a List<T>en Dictionary<K, V>crea una colección con una estructura completamente nueva.
  • La transformación de a HashSet<T>en a List<T>elimina la propiedad de unicidad de los conjuntos.

Los métodos con el prefijo Asno hacen ninguna de estas cosas, simplemente proporcionan una vista alternativa de la colección original. Lo enriquecen.

dcastro
fuente
41
Entonces, en una manzana podría llamar .AsCleanApple()porque solo necesito lavarla, y .ToFruitSalad()porque mi cuchillo cambiaría la estructura de la manzana‽
Physikbuddha
3
@Physikbuddha Básicamente, sí.
MKII
38
@Physikbuddha Me parece como AsCleanAppleva a cambiar algo acerca de la manzana. Una mejor analogía podría serAsFruit
dcastro
4
.AsCleanAppleSource()convertiría algo que fuera una fuente de manzanas en algo que fuera una fuente de manzanas limpias; agregando un paso de lavado si es necesario, pero tal vez sin hacer nada si ya se sabía que las manzanas estaban limpias. .ToPunnet()accedería a esa fuente y le daría una canasta de manzanas.
Jon Hanna
2
Esto no es estrictamente cierto, pero en general puede pensar en "AsXXX ()" como un elenco y "ToXXX ()" como una conversión.
nateirvin
26

En Linq, ToXXXtodos los métodos ejecutan la consulta y crean un nuevo objeto a partir de los resultados, mientras que los AsXXXmétodos producen una nueva consulta que es diferente de alguna manera. Puede ser el mismo objeto pero al que se accede a través de una interfaz diferente ( AsEnumerable()hace esto) o puede ser un objeto nuevo que altera la funcionalidad (los otros métodos hacen esto, aunque algunos verifican si pueden devolver el objeto dado, por ejemplo AsQueryable(), volver sourcesi IQueryable<T>ya se implementa , o crear una nueva en EnumerableQuery<TElement>caso contrario).

Jon Hanna
fuente
that alters how the functionality- ¿Es howinnecesario o debería haber una parte siguiente de la declaración?
Kapol
@Kapol no, solo un error tipográfico causado por escribir y escribir al mismo tiempo.
Jon Hanna
Creo que esta es la respuesta correcta, es decir, una proyección activa versus estática de la instancia original. ToXXX()proyecta los datos sin relación con el original. AsXXX()mantiene una relación activa con el original (al menos en los ejemplos enumerables / consultables que estamos discutiendo).
Tim Medora
+1 para ToXXX execute the queryy AsXXX produce a new query. Suena bien por lo que he leído en LINQ, y MSDN parece confirmar para ToXXX , pero me pregunto si alguien tiene una fuente para saber si todos los AsXXX métodos son ejecución diferida.
brichins
1
@brichins, ¿hay una forma significativa de decir "todos" dado que cualquiera de nosotros podría venir con un nuevo proveedor que agregue uno nuevo AsXXXademás de los inherentes a Linq (por ejemplo, el AsParallelagregado por PLinq, el AsNoTrackingproporcionado por Entity Framework, y así). Ciertamente, el núcleo de linq es lo que se define por Queryabley Enumerable, y esas dos clases siguen esa convención. La mayoría de las adiciones lo hacen, en la medida en que "todas" probablemente sean correctas, pero es demasiado abierto para garantizar que siempre sea correcto (aunque yo consideraría cualquier ruptura como un defecto de diseño).
Jon Hanna