2010-12-10 9 views
13

Ich brauche Beratung über Strukturen.C# -Compiler-Fehler: "kann keine Instanz Feldinitialisierer in Strukturen haben"

Ich habe 2 Abschnitte des Codes. Der erste Abschnitt ist wie folgt:

namespace Project.GlobalVariables 
{ 
    class IOCard 
    { 
     struct InputCard 
     { 
      public string CardNo; 
      public int BaseAddress; 
      public int LowerAddress; 
      public int UpperAddress; 
      public int[] WriteBitNo = new int[16]; 
      public int[] ReadBitNo = new int[16]; 
     } 

     static InputCard[] InputCards = new InputCard[5]; 

     public static string ACardNo = InputCards[1].CardNo; 
     public static string BCardNo = InputCards[2].CardNo; 

    } 
} 

Der zweite Teil ist wie folgt:

private void Form1_Load(object sender, EventArgs e) 
    { 
     IOCard.ACardNo = "Card A"; 
     IOCard.BCardNo = "Card B"; 

     MessageBox.Show(IOCard.ACardNo); 
     MessageBox.Show(IOCard.BCardNo); 
    } 

Mein Plan ist in der Lage sein InputCards Komponente zuweisen und Abrufen unter Verwendung IOCard wie in Form1_Load gezeigt.

Wenn ich jedoch den Code kompiliere, erhalte ich den folgenden Fehler.

Error 1 'Project.GlobalVariables.IOCard.InputCard.WriteBitNo': cannot have instance field initializers in structs E:\Programming\New platform\StandardPlatform\StandardPlatform\Project\GlobalVariables.cs 16 26 StandardPlatform

Kann mir jemand sagen, wie ich den Fehler beheben kann? Bitte beraten. Vielen Dank.

Hier sind die Klassen, die ich zu erstellen und zu verwenden versucht habe, aber fehlgeschlagen.

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

namespace Project.GlobalVariables 
{ 
    static class IOCard 
    { 
     public const int TotalInputCard = 10; 
     public const int TotalOutputCard = 10; 

     public class InputCard 
     { 
      public string CardNo = "1"; 
      public int BaseAddress; 
      public int LowerAddress; 
      public int UpperAddress; 
      public int[] WriteBitNo = new int[16]; 
      public int[] ReadBitNo = new int[16]; 
     } 

     public class OutputCard 
     { 
      public string CardNo; 
      public int BaseAddress; 
      public int LowerAddress; 
      public int UpperAddress; 
      public int[] WriteBitNo = new int[16]; 
      public int[] ReadBitNo = new int[16]; 
     } 

     public static InputCard[] InputCards = new InputCard[TotalInputCard]; 
     public static OutputCard[] OutputCards = new OutputCard[TotalOutputCard]; 

     public static int X100 = InputCards[0].WriteBitNo[0]; 
     public static int Y100 = OutputCards[0].WriteBitNo[0]; 
    } 
} 

Ich habe versucht, diese in der , wie so zu verwenden:

private void Form1_Load(object sender, EventArgs e) 
{ 
    IOCard.X100 = 1; 
    IOCard.Y100 = 1; 
} 

Egal, wie viel ich habe nach Antworten auf dem Netz suchen versucht, ich habe nirgendwo bekam.

Bitte beraten. Vielen Dank.

Antwort

1

Verwenden Sie Klasse statt Struktur. Struktur wird für kleine Typen wie Point verwendet, die auf dem Stapel schneller erstellt und kopiert werden können als dynamisch erstellt und als Referenz übergeben werden.

+0

Entschuldigung. Konnte nicht verstehen, was Sie mit "als dynamisch erstellen" meinen? –

+1

Wenn Sie eine Strukturvariable an eine Funktion übergeben oder von einer Funktion zurückgeben, wird die gesamte Variable kopiert ("dynamisch erstellt"). Wenn Sie eine Klassenvariable übergeben, wird nur ein Verweis auf diese Instanz gesendet. Wenn die Daten kleiner als 16 Byte sind, ist es tatsächlich schneller, die gesamte Instanz zu kopieren, als einen Verweis darauf zu übergeben. Wenn eine Struktur größer wird, wird sie langsamer, da viel mehr Daten kopiert werden müssen, wenn sie irgendwo übergeben werden. – Excrubulent

1

Nicht sicher über die Ausnahme, aber ich habe eine Lösung.

Sie sollten nicht "struct" für diese Klasse verwenden, es ist zu viel (und speichert zu viele Daten). Wenn Sie es als "Klasse" definieren, würde derselbe Code funktionieren.

5

Sie können weder die Felder struct initialisieren noch einen Standardkonstruktor zum Initialisieren der Felder definieren. Nach dem Betrachten Ihrer struct, empfehle ich, stattdessen eine class zu verwenden. Es wird nicht empfohlen, ein struct für ein Szenario zu verwenden, in dem Sie eine Reihe von Feldern haben.

+0

Richtlinien für wann 'struct' zu verwenden: http://msdn.microsoft.com/en-us/library/y23b5415%28VS.71%29.aspx – decyclone

1

Gibt es einen bestimmten Grund, warum Sie möchten, dass dies ein struct anstatt ein class ist?

Wenn Sie es zu einem class machen, funktioniert es ganz gut.

9

Was ist es zu sagen versucht, dass, wenn Sie InputCards = new InputCard[5]; haben es einen Speicherblock 5-mal die Größe einer InputCard Struktur zuordnen und alle seine Bytes auf 0 gesetzt Es gibt keine Möglichkeit, die int[] WriteBitNo = new int[16]; und solche Aufgaben auszuführen Also kannst du sie nicht haben.

Sie können entweder manuell einen Initialisierer für Ihre Strukturen aufrufen oder eine Klasse erstellen und das Array InputCards manuell mit 5 neuen Instanzen von InputCard initialisieren.

1

Versuchen Sie dies.Initialisieren der mit einer Fabrik InputCard Funktion Create():

namespace Project.GlobalVariables 
{ 
    class IOCard 
    { 
     struct InputCard 
     { 
      public string CardNo; 
      public int BaseAddress; 
      public int LowerAddress; 
      public int UpperAddress; 
      public int[] WriteBitNo; 
      public int[] ReadBitNo; 

      static InputCard Create() 
      { 
       return new InputCard() 
       { 
        CardNo = string.Empty, 
        WriteBitNo = new int[16], 
        ReadBitNo = new int[16] 
       }; 
      } 
     } 

     static InputCard[] InputCards = new InputCard[] 
     { 
      InputCard.Create(), 
      InputCard.Create(), 
      InputCard.Create(), 
      InputCard.Create(), 
      InputCard.Create() 
     }; 

     public static string ACardNo = InputCards[1].CardNo; 
     public static string BCardNo = InputCards[2].CardNo; 

    } 
} 
+0

Danke für den Rat. Wie könnte ich das im Unterricht machen? Irgendein Beispielcode? Vielen Dank. – JoJo

1

In C#, ein struct Wert keine Referenz auf ein Objekt in dem Weg ein Wert eines class Typ ist. Der Wert einer struct ist die "Union" aller Werte der Instanzfelder der struct.

Jetzt ist der Standardwert eines struct Typs der Wert, bei dem alle diese Felder ihre Standardwerte haben. Seit dem Beginn der C#, die Syntax:

new S() // S is a value-type 

wo S ein struct-Typ ist, hat sich auf den Standardwert dieses struct äquivalent sind. Es gibt keinen Konstruktoraufruf! Dies ist genau die gleiche Wert, der kann (heute) auch

default(S) // S is a value-type 

jetzt geschrieben werden, Dinge wie

struct S 
{ 
    int field = 42; // non-static field with initializer, disallowed! 

    // ... 
} 

sind illegal (nicht Instanzfeld initializers in structs haben). Sie könnten den Eindruck erwecken, dass die field einer new S()42 wäre, aber tatsächlich muss die field von new S() der Standardwert von int sein (was null ist, verschieden von 42).

Mit dieser Erklärung sehen Sie auch, warum es in C# not possible to create a non-static, zero-parameter constructor for a struct type ist.