Ошибка компилятора С#: "не может иметь инициализаторы полей экземпляра в структурах"

Мне нужны советы по структурам.

У меня есть 2 раздела кода. Первый раздел выглядит следующим образом:

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;

    }
}

Вторая часть выглядит следующим образом:

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

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

Мой план состоит в том, чтобы иметь возможность назначать и извлекать компонент InputCards с помощью IOCard, как показано в Form1_Load.

Однако, когда я компилирую код, я получаю следующую ошибку.

Ошибка 1 'Project.GlobalVariables.IOCard.InputCard.WriteBitNo': не может иметь инициализаторы полей экземпляра в структурах E:\Programming\New platform\StandardPlatform\StandardPlatform\Project\GlobalVariables.cs 16 26 StandardPlatform

Может ли кто-нибудь сказать мне, как решить эту ошибку? Пожалуйста, порекомендуйте. Спасибо.

Вот классы, которые я пытался создать и использовать, но не удалось.

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

Я попытался использовать их в Form_Load, например:

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

Независимо от того, насколько я пытался искать в сети ответы, я нигде не попал.

Просьба сообщить. Спасибо.

Ответы

Ответ 1

То, что он пытается сказать, заключается в том, что когда у вас есть InputCards = new InputCard[5];, он выделяет блок памяти в 5 раз больше размера структуры InputCard и устанавливает все его байты в 0. Нет возможности выполнить команду int[] WriteBitNo = new int[16]; и таких назначений, поэтому вы не можете их использовать.

Ваши варианты - либо вручную вызвать инициализатор для ваших структур, либо сделать его классом, и вручную инициализировать массив InputCards с 5 новыми экземплярами InputCard.

Ответ 2

Вы не сможете инициализировать поля struct или не задавать конструктор по умолчанию для инициализации полей. Посмотрев на struct, я рекомендую вместо этого использовать class. Не рекомендуется использовать struct для сценария, в котором у вас есть куча полей.

Ответ 3

Используйте класс вместо структуры. Структура используется для небольших типов, таких как Point, которые быстрее создаются в стеке и копируются, чем для динамического создания и передачи по ссылке.

Ответ 4

Не знаю об исключении, но у меня есть решение.

Вы не должны использовать "struct" для этого класса, это слишком много (и хранит слишком много данных). Если вы определите его как "класс", тот же код будет работать нормально.

Ответ 5

Есть ли какая-то особая причина, по которой вы хотите, чтобы это было struct, а не class?

Если вы сделаете его class, он работает отлично.

Ответ 6

Попробуйте это. Инициализируйте InputCard с помощью функции factory 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; 

    } 
}

Ответ 7

В С# значение struct не является ссылкой для объекта, как это имеет значение типа class. Значение a struct является "объединением" всех значений полей экземпляра struct.

Теперь значением по умолчанию для типа struct является значение, в котором все эти поля имеют значения по умолчанию. Начиная с начала С#, синтаксис:

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

где S - тип структуры, эквивалентен стандартным значениям этой структуры. Нет вызова конструктора! Это то же самое значение, которое может (в настоящее время) также записываться

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

Теперь такие вещи, как

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

  // ...
}

являются незаконными (не могут иметь инициализаторы полей экземпляра в структурах). Они могут создать впечатление, что field для new S() будет 42, но на самом деле field of new S() должно быть значением по умолчанию int (которое равно нулю, отличному от 42).

С этим объяснением вы также видите, почему это невозможно создать нестатический конструктор нулевого параметра для типа структуры на С#.