Pregunta

Para utilizar la sintaxis de inicialización de la siguiente manera:

var contacts = new ContactList
{
    { "Dan", "dan.tao@email.com" },
    { "Eric", "ceo@google.com" }
};

... mi entendimiento es que mi tipo ContactList sería necesario definir un método Add que toma dos parámetros string:

public void Add(string name, string email);

¿Qué es un poco confuso para mí de esto es que la sintaxis de inicializador { } parece de sólo lectura o al crear colecciones de tamaño fijo más útiles . Después de todo se quiere decir para imitar la sintaxis de inicialización para un array , ¿verdad? (OK, por lo que las matrices no son de sólo lectura;. Pero son Tamaño fijo) y, naturalmente, sólo puede utilizarse cuando el contenido de la colección son conocidos (por lo menos el número de elementos) en tiempo de compilación .

Por lo que sería casi parece que el requisito principal para utilizar esta colección inicializador sintaxis (con un método Add y por lo tanto una colección mutable) está en desacuerdo con el caso típico en el que sería más útil.

Estoy seguro de que no he puesto mucha atención en que este asunto ya que el equipo de diseño # C; pero parece que podría haber habido diferentes reglas para esta sintaxis que habría malla mejor con sus escenarios de uso típicos.

¿Estoy fuera de lugar aquí? Es el deseo de utilizar la sintaxis { } para inicializar colecciones de tamaño fijo no es tan común como pienso? ¿Qué otros factores podrían haber influido en la formulación de los requisitos de esta sintaxis que estoy simplemente no pensando?

¿Fue útil?

Solución

La razón de esto es que fue reforzado. Estoy de acuerdo con usted en que el uso de un constructor teniendo una colección haría mucho más sentido, pero no todas las clases de colección existentes implementado este y el cambio debería (1) trabajo con todas las colecciones existentes, (2) no cambiar las clases existentes en cualquier camino.

Es un compromiso.

Otros consejos

Estoy seguro de que no he puesto mucha atención en que este asunto ya que el equipo de diseño # C; pero parece que podría haber habido diferentes reglas para esta sintaxis que habría malla mejor con sus escenarios de uso típicos.

Su análisis es muy bueno; el problema clave es las tres últimas palabras en la declaración anterior. ¿Cuáles son los reales escenarios de uso típicos

El por diseño meta motivado por los escenarios de uso típicos para inicializadores de colección era hacer inicialización de tipos de colección existente es posible en un expresión de sintaxis de modo que los inicializadores de recolección podrían ser incrustado en consulta por comprensión o convertidos en árboles de expresión .

Cada otro escenario fue menor prioridad; existe la característica del todo porque ayuda a hacer el trabajo de LINQ.

El C # equipo 3 compilador fue el "polo larga" para esa versión de Visual Studio / .NET - tuvimos la mayor cantidad de días de trabajo en el horario de cualquier equipo, lo que significaba que cada día nos retrasamos, el producto sería retrasado. Quisimos enviar un producto de calidad a tiempo para todos ustedes, y lo perfecto es enemigo de lo bueno. Sí, esta característica es un poco torpe y no hace absolutamente todo lo que podría querer que, pero era más importante hacer las cosas sólido y probado para LINQ que hacer que funcione para un montón de tipos de colección inmutables que en gran parte no lo hicieron incluso existen .

Si esta función ha diseñado a la lengua desde el primer día, , mientras que los tipos de marcos seguían evolucionando , estoy seguro de que las cosas habrían sido diferentes. Como hemos discutido en otra parte de este sitio, me gustaría mucho tener una matriz de tamaño fijo de una sola escritura, muchas lecturas de valores. Sería bueno para definir un patrón común para proferir un montón de estado para inicializar una colección arbitraria inmutable. Tienes razón en que la colección inicializador sintaxis sería ideal para una cosa así.

Las características como las que hay en la lista de posibles futuras versiones de idioma hyptothetical, pero no real en lo alto de la lista. En otras palabras, vamos a llegar asíncrono / Await derecho primero antes de pensar demasiado en azúcares sintácticas para la inicialización de recogida inmutable.

Se debe a que la declaración de inicialización es la abreviatura del CLR. Cuando se compila en bytecode, se llamará al método Add que haya definido.

Por lo que puede hacer el caso de que esta declaración de inicialización no es realmente una característica de "primera clase", ya que no tiene una contraparte en IL. Pero ese es el caso de un buen montón de lo que usamos, el "uso" comunicado por ejemplo.

La razón principal es sintáctica azúcar .

La sintaxis de inicialización sólo hace escribir programando en C # un poco más fácil. En realidad, no añade ninguna fuerza expresiva de la lengua.

Si el inicializador no requería un método Add(), entonces sería una característica muy diferente de lo que es ahora. Básicamente, no es sólo cómo funciona # C. No hay forma literal para la creación de colecciones generales.

No es una respuesta, en sentido estricto, pero si quieres saber qué tipo de cosas influyó en el diseño de inicializadores de colección entonces es probable que encuentre este interesante:

¿Qué debe el uso de sintaxis de inicialización, si no es un método Add? La sintaxis de inicialización es 'correr' después de ejecutar el constructor de la colección, y la colección totalmente creado. Tiene que ser algunos manera de añadir elementos a la colección después de haber sido creado.

Si desea inicializar una colección de sólo lectura, lo hacen en el constructor (teniendo un argumento T[] items o similar)

Por lo que yo entiendo, la colección inicializador sintaxis es simplemente sin trucos especiales en el mismo. Fue diseñado en parte para apoyar la inicialización de las colecciones dentro de las consultas LINQ:

from a in somewhere
select new {
   Something = a.Something
   Collection = new List<object>() {
      a.Item1,
      a.Item2,
      ...
   }
}

Antes no había manera de hacer esto en línea y usted tendría que hacerlo después del caso, lo cual era molesto.

Me gustaría tener la sintaxis de inicializador para tipos inmutables (ambas colecciones y tipos normales). Creo que esto podría ser implementado con una sobrecarga del constructor especial utilizando una sintaxis similar a params.

Por ejemplo algo como esto:

MyClass(initializer KeyValuePair<K,V>[] initialValues)

Sin embargo, por desgracia, el equipo de C # No llevó a cabo tal cosa sin embargo: (

Así que tenemos que utilizar una solución como

MyClass(new KeyValuePair<K,V>[]{...})

por ahora

inicializadores de cobro son expresiones , para que puedan ser utilizados en el que sólo la expresión son válidos, tales como un campo de inicialización o consulta LINQ. Esto hace que su existencia muy útil.

También creo el tipo { }-rizado entre corchetes de la inicialización, los olores más como una colección de tamaño fijo, pero es sólo una opción de sintaxis.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top