2009-01-05 22 views
18

que desea inicializar una colección estática dentro de mi clase C# - algo como esto:¿Cuál es la forma correcta de inicializar una colección estática no vacía en C# 2.0?

public class Foo { 
    private static readonly ICollection<string> g_collection = ??? 
} 

No estoy seguro de la forma correcta de hacer esto; en Java podría hacer algo como:

private static final Collection<String> g_collection = Arrays.asList("A", "B"); 

¿Existe una construcción similar en C# 2.0?

Sé en versiones posteriores de C# /. NET que puede hacer inicializadores de colección (http://msdn.microsoft.com/en-us/library/bb384062.aspx), pero la migración no es una opción para nuestro sistema en este momento.

Para aclarar mi pregunta original, estoy buscando una manera de declarar de manera sucinta una colección estática simple, como una simple colección constante de cadenas. La forma de estilo de inicialización estática también es muy útil para conocer colecciones de objetos más complejos.

Gracias!

Respuesta

27

Si entiendo totalmente su pregunta, parece que algunos otros han perdido el punto, Está buscando crear una colección estática de manera similar a Java, ya que puede declarar y completar en una sola línea de código sin tener que crear un método dedicado para hacerlo (según algunas de las otras sugerencias). Esto se puede hacer usando un literal de matriz (escrito más de dos líneas para evitar el desplazamiento):

private static readonly ICollection<string> Strings = 
    new string[] { "Hello", "World" }; 

Este tanto declara y rellena la nueva colección de sólo lectura con la lista de elementos de una sola vez. Funciona en 2.0 y 3.5, lo probé solo para estar doblemente seguro.

En 3.5, aunque se puede utilizar la inferencia de tipos por lo que ya no es necesario utilizar la matriz de cadena [] que elimina aún más las pulsaciones de teclado:

private static readonly ICollection<string> Strings = 
    new[] { "Hello", "World" }; 

Aviso a los desaparecidos tipo "cadena" en la segunda línea de la línea. La cadena se deduce automáticamente del contenido del inicializador de la matriz.

Si desea rellenar como una lista, basta con cambiar a la nueva cadena [] para la nueva lista a la:

private static readonly ICollection<string> Strings = 
    new List<string>() { "Hello", "World" }; 

Por supuesto, debido a que su tipo es IEnumerable en lugar de una aplicación específica, si desea acceder a métodos específicos a la lista < cadena> como .ForEach(), tendrá que convertirlo a la lista:

((List<string>)Strings).ForEach(Console.WriteLine); 

pero es un pequeño precio a pagar por la capacidad de migración [es que una palabra?] .

+0

Sí, esta fue mi intención: editaré la pregunta para que quede más clara. ¡Gracias! –

5

Tal vez usted puede llamar a un método estático:

public class Foo 
{ 
    private static readonly ICollection<string> g_collection = initializeCollection(); 

    private static ICollection<string> initializeCollection() 
    { 
     ... TODO allocate and return something here ... 
    } 
} 

O tener un constructor estático (como otras personas sugirieron) podría ser equivalente, o incluso más idiomática.

0

La única forma en que puedo pensar sería tener un constructor estático. Entonces, primero debes actualizar una nueva colección en el nivel de clase, luego en tu constructor estático, agregarle todos los valores.

0

se podría declarar una clase de colección personalizada y añadir su propio Héctor a ella ...

public class MyFooCollection: Collection<string> 
    { 
     public MyFooCollection(string[] values) 
     { 
      foreach (string s in values) base.Add(s); 
     } 
    } 

después en su código de cliente se podría escribir

private static final MyFooCollection g_collection = 
     new MyFooCollection(new string[] {"A", "B"}); 
9

construcción estática:

public class Foo 
{ 
    private static readonly ICollection<string> _collection; 

    static Foo() 
    { 
     _collection = new List<string>(); 
     _collection.Add("One"); 
     _collection.Add("Two"); 
    } 
} 

Pero tenga en cuenta que en este caso puede simplemente inicializar la colección en línea (recomendado para performance reasons):

private static readonly ICollection<string> _collection = new List<string>(new string[] { "One", "Two" }); 

Realmente depende de la complejidad de su código de inicialización es.

+0

Puede mejorar aún más la legibilidad del código ajustando un poco más la inicialización: ... = new List () {"one", "two"}; – BenAlabaster

+2

+1 para la segunda sugerencia. – Quibblesome

0

Me gusta usar IEnumerable<T>.ToList().
Además, si su colección debe ser de solo lectura, puede usar un System.Collections.ObjectModel.ReadOnlyCollection.

private readonly ICollection<string> collection = new string[] { "a", "b", "c" }.ToList(); 

private readonly ReadOnlyCollection<string> collection2 = new ReadOnlyCollection<string>(new string[] { "a", "b", "c" }); 

EDIT:
Por otra parte, si se está usando como un ICollection, puede simplemente usar el constructor array (desde T[] es un IList<T> y un ICollection<T>). Tenga en cuenta que en este caso muchos métodos tales como alterring Agregar fallarían:

private readonly ICollection<string> = new string[] { "a", "b", "c" }; 

editar # 2: ToList me he dado cuenta es una función de extensión y sólo se puede utilizar en C# 3.0.Puede seguir utilizando el constructor Lista sin embargo:

private readonly IList<string> = new List<string>(new string[] { "a", "b", "c" }); 

Aún así, prefiero ReadOnlyCollection de sólo lectura listas.

0

Utilice un constructor estático de la siguiente manera:

public class Foo 
{ 
    static readonly ICollection<string> g_collection; 

    // Static constructor 
    static Foo() 
    { 
     g_collection = new List<string>(); 
     g_collection.Add("Hello"); 
     g_collection.Add("World!"); 
    } 
} 
1

además de constructor estático, esto también funcionará

public class Foo 
    { 
     private static readonly ICollection<string> _collection = 
       new List<string>(new string[] { "elem1", "elem2", "...", "elemn" }); 
    } 
0

tiene dos opciones:

  1. utilizar el valor de retorno de un método estático para inicializar la colección.

  2. Utilice un constructor estático para crear la colección, rellenarla e inicializarla a la variable estática.

Desde una perspectiva de rendimiento opción 1 es mejor, ya que en el caso de los constructores estáticos, el tiempo de ejecución tiene que comprobar si el constructor estático se llama antes de cada acceso a la clase.

Cuestiones relacionadas