Любопытство: преобразование структуры C # в объект все еще копирует это - PullRequest
1 голос
/ 10 июня 2011

Этот вопрос скорее из любопытства, чем из реальной проблемы. Рассмотрим следующий код (C # 4.0, если это имеет значение):

class Program {
  static Point myPoint = new Point(3, 5);

  static void Main(string[] args) {
    Console.WriteLine("Point Struct Before: " + myPoint);
    object point = GetPoint();
    Console.WriteLine("Point Object Before: " + point);
    myPoint.X = 10;
    Console.WriteLine("Point Struct After: " + myPoint);
    Console.WriteLine("Point Object After: " + point);
  }

  static object GetPoint() {
    return myPoint;
  }
}

Это выводит следующее:

Point Struct Before: 3;5
Point Object Before: 3;5
Point Struct After: 10;5
Point Object After: 3;5

Теперь это работает как надо, то есть точка, возвращаемая GetPoint(), копируется, а не ссылается. (В противном случае в последней строке также будет указано «10; 5».)

Мой вопрос сейчас: почему это работает? Как компилятор узнает, копировать или ссылаться на объект? Означает ли это, что это решение принимается во время выполнения, а не во время компиляции?

Кроме того, теперь это позволяет мне установить point на null, тогда как struct s нельзя установить на null. Является ли структура автоматически преобразуемой в обнуляемый тип?

Ответы [ 4 ]

8 голосов
/ 10 июня 2011

Кроме того, теперь это позволяет мне установить нулевое значение, тогда как структуры не могут быть установлены на нулевое значение.Является ли структура автоматически преобразуемой в обнуляемый тип?

Вы неправильно понимаете весь процесс:

int i = 5;
object o = i; //Creates a new Int32 with value 5 and assigns it to the object'o' reference storing the value on the garbage collected heap. This is what is called boxing.
object o = null //Simply assigns 'null' to the object reference, it does nothing to the boxed value type 'o' was referencing before.

В приведенном выше примере в штучной упаковке int в конечном итоге будет собраноGC из кучи собранного мусора, поскольку на него больше не указывает ни одна реальная ссылка.

4 голосов
/ 10 июня 2011

Вы не конвертируете myPoint в объект, вы просто создаете копию структуры myPoint (с помощью метода GetPoint) и присваиваете ей ссылку на объект.

4 голосов
/ 10 июня 2011

Вы наблюдаете процесс под названием бокс .По сути, он преобразует тип значения в ссылочный тип.

2 голосов
/ 16 июня 2011

Хотя Microsoft в некотором смысле утверждает, что все типы являются производными от объекта, более полезно рассматривать типы значений как вещи, которые полностью находятся вне системы типов, но которые имеют коробочные эквиваленты в системе ввода (все из которых происходят от ValueType), наряду с расширяющимися операторами преобразования между ними и эквивалентами в штучной упаковке.Если кто-то передает структуру подпрограмме, которая ожидает Object, он на самом деле передает не тип значения, а скорее коробочный эквивалент типа значения.Если это передается другим подпрограммам, которые ожидают Object, они будут продолжать использовать тот же упакованный объект.Если он передается подпрограммам, которые ожидают структуру, он будет преобразован обратно в структуру для использования с этими подпрограммами.Обратите внимание, что каждый раз, когда он конвертируется, делается снимок значения;изменения в снимке не влияют на скопированный объект, и наоборот.

...