2008-11-21 18 views

Antwort

46

Erstens tun Sie wirklich eine veränderbare Struktur haben müssen? Sie sind böse. Ebenso öffentliche Felder.

Other than that, würde ich erstellen Sie einfach einen Konstruktor die zwei Bits von Daten unter:

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) 
     }); 
} 

Beachten Sie die Verwendung von ReadOnlyCollection anstelle der Anordnung des Aussetzens selbst - das wird es unveränderlich machen, die Vermeidung the problem exposing arrays directly. (Die Code-Show initialisiert ein Array von Strukturen - es übergibt dann einfach den Verweis auf den Konstruktor ReadOnlyCollection<>.)

+2

@ Chris initialisieren: Nein, ich würde sagen, dass es weit mehr als nur öffentlich Verbrauch APIs geht. Wie groß ist dein Team? Arbeiten Sie immer für diese Firma? Wie sicher bist du, dass * jedes Mitglied deines Teams * jetzt und für immer die vielen und unterschiedlichen Ungerade veränderbarer Strukturen versteht? Für Wegwerf-Code würde ich zustimmen ... aber der meiste Code lebt viel länger im Wartungsmodus als wir ursprünglich erwarten, und schlechtes Design kann es schwerer machen, das später zu entwirren. Du findest, dass jemand ein Feld als Referenz weitergegeben hat und dann kannst du keine Eigenschaften umstrukturieren, ohne es zu zerstören usw. –

+0

Awesome John, du hast mir gerade einen neuen Blickwinkel der modernen objektorientierten Programmierung eröffnet. Danke .. – Adarsha

+3

Es ist eine Schande, dass hier so viel extra tippen ist. In C++ 11 kann ich tun: 'struct foo {int i; const char * str; Zeichen c; }; foo f [] = {{1, "Hallo", "c"}, {2, "Auf Wiedersehen", "d" "}};' Es wäre nett, wenn man den Konstruktor nicht schreiben müsste oder muss "new foo" so viel schreiben. – Bklyn

22

Verwenden Sie C# 3.0? Sie können Objektinitialisierer wie folgt verwenden:

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

Mit C# 3 brauchen Sie nicht() für jeden Konstruktoraufruf (da Sie einen Objektinitialisierer verwenden) und Sie können das Bit "new MyStruct []", wie es impliziert ist, weil es der Initialisierer für ein Array ist, ablegen Variable. –

+0

Um klar zu sein, trotz des Erscheinens und des Fehlens von "neu" wird dies immer noch ein Array auf dem Heap zuweisen, nicht den Stack. – yoyo

3

Sie können Referenztypen standardmäßig nicht null initialisieren. Sie müssen sie nur lesen. Das könnte also funktionieren.

+5

Beachten Sie, dass dies die Variable nur schreibgeschützt macht - sie verhindert nicht, dass anderer Code Elemente im Array ersetzt. –

+1

Diese Lösung hat für mich funktioniert. Es ist eine Schande, dass wir nicht etwas so dicht und effizient wie alte C-style Array/Struct Initialisierer haben. –

-2

Ich würde einen statischen Konstruktor für die Klasse verwenden, der den Wert eines statischen schreibgeschützten Arrays festlegt.

public class SomeClass 
{ 
    public readonly MyStruct[] myArray; 

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

Ein Zugriffsmodifizierer ist für statische Konstruktoren nicht zulässig –

0

ändern const-static readonly und es so

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