2008-11-21 25 views

Respuesta

46

En primer lugar, ¿verdad realmente tiene que tener una estructura mutable? Ellos son malvados Del mismo modo, campos públicos.

Aparte de eso, me acabo de crear un constructor teniendo los dos bits de datos:

class SomeClass 
{ 

    struct MyStruct 
    { 
     private readonly string label; 
     private readonly int id; 

     public MyStruct (string label, int id) 
     { 
      this.label = label; 
      this.id = id; 
     } 

     public string Label { get { return label; } } 
     public string Id { get { return id; } } 

    } 

    static readonly IList<MyStruct> MyArray = new ReadOnlyCollection<MyStruct> 
     (new[] { 
      new MyStruct ("a", 1), 
      new MyStruct ("b", 5), 
      new MyStruct ("q", 29) 
     }); 
} 

Nota el uso de ReadOnlyCollection en lugar de exponer la matriz misma - esto hará que sea inmutable, evitando the problem exposing arrays directly. (El programa de códigos inicializa un conjunto de estructuras; luego pasa la referencia al constructor de ReadOnlyCollection<>).

+2

@ Chris: No, yo diría que va mucho más allá de simplemente API públicamente consumibles. ¿Qué tan grande es tu equipo? ¿* Siempre * vas a trabajar para esa compañía? ¿Cuán seguro estás de que * cada miembro de tu equipo *, ahora y para siempre, entiende las muchas y variadas rarezas de las estructuras mutables? Para el código descartable, estaría de acuerdo ... pero la mayoría del código vive mucho más en el modo de mantenimiento de lo que originalmente esperábamos, y un diseño deficiente puede hacer que sea mucho más difícil desentrañarlo más adelante. Encuentra que alguien ha pasado un campo por referencia y luego * no * puede refactorizar a las propiedades sin romperlo, etc. –

+0

Impresionante John, me acaba de dar cuenta de un nuevo ángulo de programación orientada a objetos moderna. Gracias .. – Adarsha

+3

Es una pena que haya tanto tipeo adicional aquí. En C++ 11 puedo hacer: 'struct foo {int i; const char * str; char c; }; foo f [] = {{1, "hola", 'c'}, {2, "adiós", 'd' "}};' Sería bueno si uno no necesitara escribir el constructor o tengo que escribir tanto " – Bklyn

22

¿Está utilizando C# 3.0? Puede usar los inicializadores de objetos de la siguiente manera:

static MyStruct[] myArray = 
      new MyStruct[]{ 
       new MyStruct() { id = 1, label = "1" }, 
       new MyStruct() { id = 2, label = "2" }, 
       new MyStruct() { id = 3, label = "3" } 
      }; 
+4

Con C# 3 no necesita el() para cada llamada al constructor (ya que está usando un inicializador de objetos) y puede deshacerse del "nuevo bit MyStruct []" como eso está implícito de todos modos debido a ser el inicializador de una matriz variable. –

+0

Para ser claros, a pesar de las apariencias y la falta de "nuevo" esto todavía asignará una matriz en el montón, no en la pila. – yoyo

3

No puede inicializar los tipos de referencia por defecto, excepto nulo. Tienes que hacerlos de solo lectura. Entonces esto podría funcionar;

readonly MyStruct[] MyArray = new MyStruct[]{ 
     new MyStruct{ label = "a", id = 1}, 
     new MyStruct{ label = "b", id = 5}, 
     new MyStruct{ label = "c", id = 1} 
    }; 
+5

Tenga en cuenta que eso solo hace que la variable sea de solo lectura, no impide que otro código reemplace elementos en la matriz. –

+1

Esta solución funcionó para mí. Es una pena que no tengamos algo tan denso y eficiente como los antiguos inicializadores array/struct estilo C. –

-2

Utilizaría un constructor estático en la clase que establece el valor de una matriz de solo lectura estática.

public class SomeClass 
{ 
    public readonly MyStruct[] myArray; 

    public static SomeClass() 
    { 
     myArray = { {"foo", "bar"}, 
        {"boo", "far"}}; 
    } 
} 
+0

Un modificador de acceso no está permitido para constructores estáticos –

0

Cambio const-static readonly y se inician como este

static readonly MyStruct[] MyArray = new[] { 
    new MyStruct { label = "a", id = 1 }, 
    new MyStruct { label = "b", id = 5 }, 
    new MyStruct { label = "q", id = 29 } 
}; 
Cuestiones relacionadas