Является ли структура упакованной при передаче методу с помощью ключевого слова ref? - PullRequest
4 голосов
/ 20 ноября 2011

Кто-нибудь знает, происходит ли бокс, когда структура передается методу, использующему ref? ключевое слово, т.е.

struct Test
{
    public int Value;
}

static void Main()
{
    Test test = new Test();
    SomeMethod(ref test);
    System.Diagnostics.Debug.WriteLine(test.Value);
}

static void SomeMethod(ref Test test)
{
    test.Value = 5;
}

Я хотел бы использовать структуру для типа, но у меня есть пара методов, которые необходимо Измени это. Если он помечается, я просто передам его и верну, или вместо этого использую класс.

Ответы [ 3 ]

2 голосов
/ 20 ноября 2011

Нет, это не так.

Вместо этого передается расположение структуры в памяти.

Однако, не делайте этого .
Изменчивые структуры: зло .

2 голосов
/ 20 ноября 2011

Бокса не будет, но, похоже, вы все равно должны использовать класс.
Лучший совет для структур состоит в том, что они должны быть неизменными, поэтому

  • почему struct на первом месте?
  • Зачем переключаться на копирование и возврат, чтобы избежать бокса? Вы предполагаете, что это быстрее?
1 голос
/ 21 ноября 2011

Чтобы что-то передавалось по ссылке, объявленный тип параметра должен точно соответствовать объявленному типу передаваемой вещи.Упаковка происходит только тогда, когда тип значения преобразуется во что-то, чей объявленный тип не является типом значения, и, следовательно, не совсем совпадает с рассматриваемым типом значения.

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

struct StructType1 {public int V; ... }
class ClassType1 {public int V; ... }

void blah()
{
  StructType1 s1;
  ClassType1 c1 = new ClassType1();
  ... do some stuff...
  Routine1(s_pt, c_pt);
  Routine2(ref s_pt, ref c_pt);
  ... do more stuff
}

Какое влияние может оказать Routine1 на S1.V?Какой эффект может иметь рутина1 на C1.V?

Какой эффект может иметь рутина2 на S1.V?Когда такие эффекты могут иметь место?Как насчет C1.V?В частности, есть ли способ узнать, может ли Routine1 или Routine2 вызвать изменение C1.V в любое произвольное время в будущем, еще долго после того, как вызов был возвращен?

Кроме того, предположим, что S1 содержит некоторые данные, которые я хочухранить в классе.Если S1 не содержит ничего, кроме типов значений (которые могут или не могут быть изменяемыми) и неизменяемых ссылочных типов, нужно ли мне беспокоиться о том, что что-то может неожиданно изменить данные, которые я там хранил?данные, которые я хотел сохранить.Если C1 является изменяемым или содержит какие-либо изменяемые ссылочные типы, и я предоставил его любым внешним функциям, есть ли способ безопасно хранить содержащуюся в нем информацию, не имея при этом достаточного количества информации о внутренностях C1?

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

...