2010-12-10 11 views
13

Necesito asesoramiento sobre estructuras.Error del compilador de C#: "no puede tener inicializadores de campo de instancia en las estructuras"

Tengo 2 secciones de código. La primera sección es la siguiente:

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; 

    } 
} 

La segunda parte es la siguiente:

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

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

Mi plan es ser capaz de asignar y recuperar InputCards componente utilizando IOCard como se muestra en Form1_Load.

Sin embargo, cuando compilo el código, aparece el siguiente error.

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

¿Alguien me puede decir cómo solucionar el error? por favor asesorar. Gracias.

Estas son las clases que he intentado crear y usar, pero han fallado.

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

He intentado utilizar estos en el , así:

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

No importa lo mucho que he tratado de buscar en la red en busca de respuestas, me han llevado a ninguna parte.

Por favor, asesorar. Gracias.

Respuesta

1

Utilice la clase en lugar de la estructura. La estructura se usa para pequeños tipos como Point, que son más rápidos de crear en la pila y copiar, que para crear dinámicamente y pasar por referencia.

+0

Disculpa. ¿No entendiste lo que quieres decir con "que crear dinámicamente"? –

+1

Cuando pasa una variable struct o la devuelve desde una función, la variable completa se copia ("creada dinámicamente"). Cuando pasa una variable de clase, solo se envía una referencia a esa instancia. Si los datos son menos de 16 bytes, en realidad es más rápido copiar toda la instancia que pasarle una referencia. Cuando una estructura crece, se vuelve más lenta porque se deben copiar muchos más datos cada vez que se pasan a otra parte. – Excrubulent

1

No estoy seguro de la excepción, pero tengo una solución.

No debe usar "struct" para esta clase, es demasiado (y almacena demasiados datos). Si lo define como "clase", el mismo código funcionaría bien.

5

No podrá inicializar los campos struct ni definir un constructor predeterminado para inicializar sus campos. Después de mirar su struct, le recomiendo que use un class en su lugar. No se recomienda utilizar struct para un escenario en el que tenga varios campos.

+0

Pautas sobre cuándo usar 'struct': http://msdn.microsoft.com/en-us/library/y23b5415%28VS.71%29.aspx – decyclone

1

¿Hay alguna razón en particular por la que desea que sea struct en lugar de class?

Si lo convierte en class, funciona bien.

9

¿De qué se trata de decir es que cuando se tiene InputCards = new InputCard[5]; se asignará un bloque de memoria 5 veces el tamaño de una estructura InputCard y establecer todos sus bytes a 0. No hay oportunidad de ejecutar las int[] WriteBitNo = new int[16]; y tales asignaciones , entonces no puedes tenerlos.

Sus opciones son invocar manualmente un inicializador para sus estructuras o convertirlo en una clase e inicializar manualmente la matriz InputCards con 5 nuevas instancias de InputCard.

1

Pruebe esto.Inicializar el InputCard con una función de fábrica 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

Gracias por el consejo. ¿Cómo podría hacerlo en clase? ¿Algún código de muestra? Gracias. – JoJo

1

En C#, un valor struct es no una referencia a un objeto en la forma en que un valor de un tipo class es. El valor de struct es la "unión" de todos los valores de los campos de instancia del struct.

Ahora, el valor predeterminado de un tipo struct es el valor en el que todos esos campos tienen sus valores por defecto. Desde el comienzo de C#, la sintaxis:

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

donde S es un tipo struct, ha sido equivalente al valor por defecto de que struct. ¡No hay llamada de constructor! Este es el mismo valor exacto que se puede (hoy en día) también puede escribir

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

Ahora, las cosas como

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

    // ... 
} 

son ilegales (no pueden tener inicializadores campo de instancia en estructuras). Podrían dar la impresión de que el field de new S() sería 42, pero de hecho el field de new S() debe ser el valor predeterminado de int (que es cero, distinto de 42).

Con esta explicación, también verá por qué es not possible to create a non-static, zero-parameter constructor for a struct type, en C#.

Cuestiones relacionadas