Какая польза от типов значений в.Net?
Официальные рекомендации предполагают, что практического использования для них может быть очень мало. У кого-нибудь есть примеры того, где они нашли хорошее применение?
8 ответов
Au Contrare... вы обнаружите, что C/C++ люди стекаются в структуры, называемые типами значений.
Примером могут быть пакеты данных. Если у вас есть большое количество пакетов данных для передачи / передачи, вы должны использовать структуры значений для моделирования ваших пакетов данных.
причина: превращение чего-либо в класс добавляет издержки (примерно 8-16 байт, которые я забыл) накладных расходов в заголовке объекта в дополнение к данным экземпляра. В сценариях, где это недопустимо, наиболее ценным вариантом является тип значения
Другим вариантом использования могут быть ситуации, когда вам нужна семантика типа значения - после создания-инициализации объекта он доступен только для чтения / неизменен и может быть передан n клиентам.
По большей части хорошо подражать поведению фреймворка. Многие элементарные типы данных, такие как int
s являются типами значений. Если у вас есть типы с похожими свойствами, используйте типы значений. Например, при написании Complex
тип данных или BigInteger
Типы значений являются логическим решением. То же самое касается других случаев, когда в каркасе используются типы значений: DateTime
, Point
, так далее.
Если есть сомнения, используйте вместо этого ссылочный тип.
Я склонен использовать enum для избежания магических чисел, думаю, это можно преодолеть с помощью const, но enum позволяет сгруппировать их.
т.е.
enum MyWeirdType {
TypeA, TypeB, TypeC};
switch(value){
case MyWeirdType.TypeA:
...
Именно для чего их использует большинство других людей. Быстрый и легкий доступ к данным / ценностям. Помимо того, что он идеален для того, чтобы объединить свойства (если это имеет смысл, конечно) в объект.
Например:
- Различия значений дисплея / данных, такие как пары строк имен изображений и путь к элементу управления (или что-либо еще). Вам нужен путь для работы под капотом, но имя должно быть видно пользователю.
- Очевидная группировка значений для метрик объектов. Мы все знаем Размер и т. Д., Но может быть много ситуаций, когда базовых "метрических" типов вам недостаточно.
- "Типирование" значений перечисления, будучи больше, чем фиксированное перечисление, но меньше, чем полноценный класс (уже упоминалось, просто хочу отстаивать).
Важно помнить различия между значениями и ссылочными типами. При правильном использовании они могут реально повысить эффективность вашего кода, а также сделать объектную модель более надежной.
Перечисления являются первоклассными гражданами мира.NET. Что касается структур, я обнаружил, что в большинстве случаев можно использовать классы, однако для сценариев с интенсивным использованием памяти рассмотрите возможность использования структур. В качестве практического примера я использовал структуры в качестве структур данных для примитивов протоколов OSCAR (ICQ).
Вы должны использовать тип значения всякий раз, когда:
- Использование класса не обязательно (нет необходимости в наследовании)
- Вы хотите убедиться, что нет необходимости инициализировать тип.
- У вас есть причина хотеть, чтобы тип был размещен в пространстве стека
- Вы хотите, чтобы тип был полностью независимой сущностью при назначении, а не "ссылкой" на экземпляр, как в ссылочных типах.
Типы значений, в частности, структуры и перечисления, и должным образом используются в объектно-ориентированном программировании.
Как уже говорилось, перечисления - это первоклассные граждане в.NET, которые могут использоваться для самых разных вещей, от цветов до опций DialogBox и различных типов флагов.
Структуры, насколько мне известно, великолепны как объекты передачи данных; Контейнеры данных без логики, особенно если они состоят в основном из примитивных типов.
И, конечно, все примитивные типы являются типами значений, которые разрешаются в System.Object (в отличие от Java, где примитивные типы не связаны со структурами и нуждаются в какой-то оболочке).
На самом деле до.net 3.5 SP1 существовала проблема производительности с интенсивным использованием типов значений, как упомянуто здесь в блоге Вэнса Моррисона.
Насколько я понимаю, в большинстве случаев вы должны использовать классы, а JITter должен гарантировать хороший уровень производительности.
Структуры имеют "семантику типа значения", поэтому будут передаваться по значению, а не по ссылке. Мы можем увидеть эту разницу в поведении в следующем примере:
using System;
namespace StructClassTest {
struct A {
public string Foobar { get; set; }
}
class B {
public string Foobar { get; set; }
}
class Program {
static void Main() {
A a = new A();
a.Foobar = "hi";
B b = new B();
b.Foobar = "hi";
StructTest(a);
ClassTest(b);
Console.WriteLine("a.Foobar={0}, b.Foobar={1}", a.Foobar, b.Foobar);
Console.ReadKey(true);
}
static void StructTest(A a) {
a.Foobar = "hello";
}
static void ClassTest(B b) {
b.Foobar = "hello";
}
}
}
Структура будет передана по значению, поэтому StructTest() получит свою собственную структуру A, и когда она изменится, a.Foobar изменит Foobar своего нового типа. ClassTest() получит ссылку на b и, следовательно, свойство.Foobar для b будет изменено. Таким образом, мы получили бы следующий вывод:
a.Foobar=hi, b.Foobar=hello
Так что если вы хотите семантику типа значения, это будет еще одна причина объявить что-то как структуру. Интересно отметить, что тип DateTime в.net является типом значения, поэтому архитекторы.net решили, что было бы целесообразно назначить его как таковой, было бы интересно определить, почему они это сделали:-)