C # Struct Нет беспараметрического конструктора? Посмотри, что мне нужно сделать - PullRequest
14 голосов
/ 03 марта 2010

Я использую структуру для передачи в неуправляемую DLL, как так -

[StructLayout(LayoutKind.Sequential)]
        public struct valTable
        {
            public byte type;
            public byte map;
            public byte spare1;
            public byte spare2;
            public int par;
            public int min;
            public byte[] name;
            public valTable()
            {
                name = new byte[24];
            }
        }

Приведенный выше код не будет компилироваться, потому что VS 2005 будет жаловаться, что "Structs не может содержать явных конструкторов без параметров". Чтобы передать эту структуру в мою DLL, я должен передать массив структур, например, valTable[] val = new valTable[281];

Что я хотел бы сделать, так это когда я говорю new, вызывается конструктор и он создает массив байтов, который я пытаюсь продемонстрировать, потому что DLL ищет этот байтовый массив размером 24 в каждом измерении.

Как мне это сделать?

Ответы [ 6 ]

20 голосов
/ 03 марта 2010

Вы можете использовать фиксированный размер буфера - который, я подозреваю, вам действительно нужен в любом случае, чтобы получить данные "inline" в структуре (а не ссылку на массив в другом месте).

public fixed byte name[24];

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

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

6 голосов
/ 03 марта 2010

Я бы порекомендовал написать этот код.

[StructLayout(LayoutKind.Sequential)]
public struct valTable
{
    public byte type;
    public byte map;
    public byte spare1;
    public byte spare2;
    public int par;
    public int min;
    public byte[] name;

    static public valTable Create()
    {
        valTable vT = new valTable();
        vT.name = new byte[24];
        return vT;
    }
}
4 голосов
/ 03 марта 2010

Опираясь на Ответ Асада Батта , вы можете создать статический метод для выполнения работы вашего конструктора следующим образом:

[StructLayout(LayoutKind.Sequential)]
public struct valTable
{
    public byte type;
    public byte map;
    public byte spare1;
    public byte spare2;
    public int par;
    public int min;
    public byte[] name;
    public valTable()

    public static valTable NewTable()
    {
        valTable tbl = new valTable();
        tbl.name = new byte[24];
        return tbl;
    }
}

Вы увидите классы в .NET Frameworkследуя этой схеме уже.Guid.NewGuid() сразу приходит на ум.Могут быть и другие.

4 голосов
/ 03 марта 2010

Конструкторы Struct похожи на конструкторы классов, за исключением следующих отличий:

  • Структуры не могут содержать явные конструкторы без параметров. Struct члены автоматически инициализируются к их значениям по умолчанию.
  • Структура не может иметь инициализатор в форме: база (список аргументов).

Это означает, что

A default(parameterless) constructor for a struct could set different
values than the all-zeroed state which would be unexpected behavior. The
.Net Runtime therefore prohabits default constructors for struct.

Типичный способ обойти этот сценарий - создать статический метод. который создаст ваш новый экземпляр, инициализирует его так, как вы хотите, и верни это. Так делается в .NET для инициализации структур с конкретными значениями.


исх; Структуры не могут содержать явных конструкторов без параметров. ПОЧЕМУ?

2 голосов
/ 03 марта 2010

Не самое чистое исправление, но вы можете просто добавить параметр и никогда не использовать его?

[StructLayout(LayoutKind.Sequential)]
    public struct valTable
    {
        public byte type;
        public byte map;
        public byte spare1;
        public byte spare2;
        public int par;
        public int min;
        public byte[] name;
        public valTable(int x)
        {
            name = new byte[24];
        }
    }
0 голосов
/ 03 марта 2010

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

...