2014-09-01 5 views
5

Я читал много литературы, которая в последнее время окружала Value Types & Reference Types, и их отличия. Этот вопрос окружает тему изменчивость и неизменяемость типов значений.Типы значений, неизменность (хорошая) и возможность использования (зла) в .NET.

Основываясь на том, что я прочитал, кажется, что типы значений в .NET должны быть написаны таким образом, чтобы они были неизменными; то есть после того, как им присвоено значение, значение этого типа в памяти никогда не изменяется. Только последующие копии типа могут создавать новые экземпляры в памяти с новыми значениями, основанными на оригинале. Казалось бы, изменчивость в .NET - это зло.

Для уточнения понимания неизменности (для моего собственного здравомыслия, и для других), я показал это ниже:

DateTime и TimeSpan примеры неизменных структур, потому что когда-то значение было назначен на экземпляр, что значение экземпляра не может измениться, это видно через свойства только для чтения:

DateTime dt = new DateTime(); 
DateTime newdt = dt.AddDays(2); // Okay, new value stored in newdt 
newdt.Year = 1945; // Error, cannot write to readonly property 

Неизменность однако, может ввести в заблуждение при поиске ar примитивные типы, такие как Int32, Double или Char, так как типы кажутся изменяемыми, но мое чувство кишки состоит в том, что на самом деле неизменяемость обрабатывается прозрачно через CLR; Возьмем, например, следующие операции (я комментировал в некоторых очень простой x86 эквивалент, чтобы понять, как неизменность обрабатывается с точки зрения примитивного типа)

int x = 0; 

// xor eax, eax;  'clear register to 0 
// push eax;   'push eax (0) onto the stack 

x = 5; 

// pop eax;   'pop stack (0) into eax 
// mov eax, 5;  'eax = 5 
// push eax;   'push eax (5) onto the stack 

x++; 

// pop eax;   'pop stack (5) into eax 
// add eax, 1;  'eax = 5 + 1 
// push eax;   'push eax (6) onto the stack 

Все хорошо до сих пор; Microsoft, похоже, делает хорошую работу по внедрению неизменности в свои типы значений; но затем мы начинаем находить плохие яблоки, а субэлементы, которые делают изменчивость, выглядят хорошо, а глупые разработчики - в ложном смысле безопасности!

Я говорю о Point, Size, Rectangle (и некоторые другие) в System.Drawing пространстве имен.

Внезапно нам дается возможность изменять тип значения по его свойствам, и у меня есть теория относительно того, почему это возможно; Возьмем, например, следующий код

Point p = new Point(); 
p.X = 100; 
p.Y = 200; 

// Immutability (had it been implemented here) might infer the following usage 

Point p = new Point(100, 200); 
Point p2 = p.AddXY(200, 300); 

Однако, как указано у меня была теория, почему эти структуры являются изменяемыми:

  1. Microsoft просто хотел, чтобы сделать его легче работать с этими структурами.
  2. Они совместимы с собственными вызовами GDI/GDI +, поэтому их поведение было разработано вокруг собственных C/C++-аналогов.

Итак, наконец, мои вопросы:

  1. ли я полностью накрывали и понял, неизменность и переменчивость?
  2. Должны ли разработчики стремиться к созданию неизменяемых структур, как правило?
  3. Когда приемлемо создавать изменчивые структуры?
+0

Существует много и много об этом на google: https://www.google.at/search?q=c%23+struct+mutability+consistency – Traubenfuchs

+0

@ ErenErsönmez Я прочитал эту статью, но даже тогда я говорят много мнения о том, почему изменчивость может считаться конструктивным решением, а не просто «злом». – series0ne

+0

Я нашел мутирующие * методы * проблемные. Простое наличие изменяемых полей или свойств с помощью сеттера не является большой проблемой. – CodesInChaos

ответ

6

Вопрос о изменчивости не относится к ссылочному типу значения. Есть примеры для обоих. Возьмите System.String как пример для неизменяемого класса, а также ваш пример System.Drawing.Point в качестве примера изменчивой структуры.

Mutable vs. immutable - это конструктивное решение, основанное на использовании этого типа. Является ли это ссылкой или типом значения другим дизайнерским решением, которое не зависит от первого.

2

Хм ... Это, вероятно, скоро будет закрыто, но вот мой взгляд на это.

  1. Да, похоже, вы понимаете неизменность и мутируемость.
  2. Должно быть большое слово. Разработчики должны знать о различиях, заботиться об их торговле и иметь здравый смысл задавать себе вопрос: что мне нужно от этой конкретной структуры.
  3. Приемлемый? Думаю, когда тебе это нужно. Вопрос , когда вам нужен один - это совсем другой вопрос.

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

Смежные вопросы