При создании массива внутри структуры, содержит ли эта структура непосредственно значение массива или ссылку памяти на этот массив? - PullRequest
0 голосов
/ 09 августа 2010

Я создаю массив, как показано ниже:

public struct Smb_Parameters
        {
            public byte WordCount;
            public ushort[] Words;
        }

Пока я присваиваю значения, как показано ниже:

Smb_Parameters smbParameter = new Smb_Parameters();
smbParameter.WordCount = 0;
string words= "NT LM 0.12";
smbParameter.Words = Encoding.ASCII.GetBytes(name);

В приведенном выше присваивании smbParameter.WordCount содержит значение 0но содержит ли smbParameter.Words непосредственно значения (Arry of byteS) или ссылку в памяти на местоположение, содержащее значения?

Изменить 1 :

Я хочу отправитьпакет на сервер.Для этого мне нужно преобразовать Smb_Parameters объект в массив, используя следующий код:

int len = Marshal.SizeOf(Smb_Parameters);
 byte[] arr = new byte[len];
 IntPtr ptr = Marshal.AllocHGlobal(len);
 Marshal.StructureToPtr(Smb_Parameters, ptr, true);
 Marshal.Copy(ptr, arr, 0, len);
 Marshal.FreeHGlobal(ptr);

1 Ответ

3 голосов
/ 09 августа 2010

Если вы не используете буферы фиксированного размера в небезопасном коде, это будет ссылка.В общем, не имеет значения, содержится ли переменная в структуре или классе - или, действительно, является ли она локальной переменной: тип переменной определяет, является ли значение ссылкой или содержит ли она данные напрямую.Помимо буферов фиксированного размера, о которых я упоминал, массивы всегда являются ссылочными типами в .NET.

(есть также stackalloc , который немного похож на распределение массива - он выделяет блокпамяти в стеке. Опять же, это только для использования в небезопасном коде, и очень редко встречается в моем опыте.)

В приведенном вами примере (соответствующим образом отрегулирован, чтобы он компилировался) Wordsопределенно будет ссылка.В частности, если вы назначите значение для ссылки на определенный массив, а затем измените содержимое этого массива, изменения будут видны через переменную структуры.

(я также настоятельно рекомендую вам не имеет открытые поля или изменяемые типы значений. Надеюсь, это только для примера:)

РЕДАКТИРОВАТЬ: Чтобы ответить на обновленный вопрос, не отправлять данныевот так .Это ужасно хрупкий способ сериализации чего-либо.Существуют различные лучшие варианты:

  • Использовать двоичную сериализацию .NET (также несколько хрупкую с точки зрения управления версиями, а не кросс-платформенную)
  • Использовать сериализацию XML (возможно, в этом случае избыточно))
  • Использовать стороннюю платформу сериализации (например, Thrift или Protocol Buffers)
  • Сериализация с использованием метода "ToByteArray" или "WriteToStream" в вашем классе, который явно сериализует каждое значение.Вы можете использовать BinaryWriter для этого.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...