Что такое value type c
Перейти к содержимому

Что такое value type c

  • автор:

Типы значений (справочник по C#)

Типы значений и ссылочные типы — это две основные категории типов C#. Переменная типа значения содержит экземпляр типа. Это отличается от переменной ссылочного типа, которая содержит ссылку на экземпляр типа. По умолчанию при назначении, передаче аргумента в метод и возврате результата метода копируются значения переменных. В случае переменных типа значения копируются соответствующие экземпляры типа. В следующем примере продемонстрировано такое поведение.

using System; public struct MutablePoint < public int X; public int Y; public MutablePoint(int x, int y) =>(X, Y) = (x, y); public override string ToString() => $"(, )"; > public class Program < public static void Main() < var p1 = new MutablePoint(1, 2); var p2 = p1; p2.Y = 200; Console.WriteLine($"after is modified: "); Console.WriteLine($": "); MutateAndDisplay(p2); Console.WriteLine($" after passing to a method: "); > private static void MutateAndDisplay(MutablePoint p) < p.X = 100; Console.WriteLine($"Point mutated in a method: 

"); > > // Expected output: // p1 after p2 is modified: (1, 2) // p2: (1, 200) // Point mutated in a method: (100, 200) // p2 after passing to a method: (1, 200)

Как показано в предыдущем примере, операции с переменной типа значения влияют только на этот экземпляр типа значения, хранящийся в переменной.

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

using System; using System.Collections.Generic; public struct TaggedInteger < public int Number; private Listtags; public TaggedInteger(int n) < Number = n; tags = new List(); > public void AddTag(string tag) => tags.Add(tag); public override string ToString() => $" []"; > public class Program < public static void Main() < var n1 = new TaggedInteger(0); n1.AddTag("A"); Console.WriteLine(n1); // output: 0 [A] var n2 = n1; n2.Number = 7; n2.AddTag("B"); Console.WriteLine(n1); // output: 0 [A, B] Console.WriteLine(n2); // output: 7 [A, B] >> 

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

Виды типов значений и ограничения типов

Тип значения может относится к одному из двух следующих видов:

  • тип структуры, который инкапсулирует данные и связанные функции;
  • тип перечисления, который определяется набором именованных констант и представляет выбор или сочетание вариантов для выбора.

Тип T? значения, допускающий значение NULL, представляет все значения базового типа T значения и дополнительное значение NULL. Вы не можете назначить null переменной типа значения, если только это не тип, допускающий значение NULL.

Вы можете использовать ограничение struct , чтобы указать, что параметр типа является типом значения, не допускающим значения NULL. Типы структуры и перечисления удовлетворяют ограничению struct . Можно использовать System.Enum в ограничении базового класса (которое называется ограничением перечисления), чтобы указать, что параметр типа является типом перечисления.

Встроенные типы значений

C# предоставляет следующие встроенные типы значений, которые также называются простыми типами.

  • Целочисленные типы
  • Числовые типы с плавающей запятой
  • bool, представляющий логическое значение
  • char, представляющий символ Юникода UTF-16

Все простые типы являются типами структур и отличаются от других типов структур тем, что разрешают некоторые дополнительные операции.

  • Литералы можно использовать для предоставления значения простого типа. Например, ‘A’ — это литерал типа char , а 2001 — литерал типа int .
  • Константы простых типов можно объявить с помощью ключевого слова const. Невозможно использовать константы других типов структур.
  • Константные выражения, операнды которых являются константами простых типов, вычисляются во время компиляции.

Кортеж значений — это тип значения, но не простой тип.

Спецификация языка C#

Дополнительные сведения см. в следующих разделах статьи Спецификация языка C#:

См. также раздел

  • справочник по C#
  • System.ValueType
  • Ссылочные типы

Совместная работа с нами на GitHub

Источник этого содержимого можно найти на GitHub, где также можно создавать и просматривать проблемы и запросы на вытягивание. Дополнительные сведения см. в нашем руководстве для участников.

Типы данных

Типы данных имеют особенное значение в C#, поскольку это строго типизированный язык. Это означает, что все операции подвергаются строгому контролю со стороны компилятора на соответствие типов, причем недопустимые операции не компилируются. Следовательно, строгий контроль типов позволяет исключить ошибки и повысить надежность программ. Для обеспечения контроля типов все переменные, выражения и значения должны принадлежать к определенному типу. Такого понятия, как «бестиповая» переменная, в данном языке программирования вообще не существует. Более того, тип значения определяет те операции, которые разрешается выполнять над ним. Операция, разрешенная для одного типа данных, может оказаться недопустимой для другого.

В C# имеются две общие категории встроенных типов данных: типы значений и ссылочные типы. Они отличаются по содержимому переменной. Концептуально разница между ними состоит в том, что тип значения (value type) хранит данные непосредственно, в то время как ссылочный тип (reference type) хранит ссылку на значение.

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

Классификация типов данных

Давайте разберем типы значений.

Целочисленные типы

В C# определены девять целочисленных типов: char, byte, sbyte, short, ushort, int, uint, long и ulong. Но тип char применяется, главным образом, для представления символов и поэтому рассматривается отдельно. Остальные восемь целочисленных типов предназначены для числовых расчетов. Ниже представлены их диапазон представления чисел и разрядность в битах:

Целочисленные типы C#

Тип Тип CTS Разрядность в битах Диапазон
byte System.Byte 8 0:255
sbyte System.SByte 8 -128:127
short System.Int16 16 -32768 : 32767
ushort System.UInt16 16 0 : 65535
int System.Int32 32 -2147483648 : 2147483647
uint System.UInt32 32 0 : 4294967295
long System.Int64 64 -9223372036854775808 : 9223372036854775807
ulong System.UInt64 64 0 : 18446744073709551615

Как следует из приведенной выше таблицы, в C# определены оба варианта различных целочисленных типов: со знаком и без знака. Целочисленные типы со знаком отличаются от аналогичных типов без знака способом интерпретации старшего разряда целого числа. Так, если в программе указано целочисленное значение со знаком, то компилятор C# сгенерирует код, в котором старший разряд целого числа используется в качестве флага знака. Число считается положительным, если флаг знака равен 0, и отрицательным, если он равен 1.

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

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

Так, если значение нужно сохранить без знака, то для него можно выбрать тип uint, для больших значений со знаком — тип long, а для больших значений без знака — тип ulong. В качестве примера ниже приведена программа, вычисляющая расстояние от Земли до Солнца в сантиметрах. Для хранения столь большого значения в ней используется переменная типа long:

using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ConsoleApplication1 < class Program < static void Main(string[] args) < long result; const long km = 149800000; // расстояние в км. result = km * 1000 * 100; Console.WriteLine(result); Console.ReadLine(); >> >

Всем целочисленным переменным значения могут присваиваться в десятичной или шестнадцатеричной системе обозначений. В последнем случае требуется префикс 0x:

long x = 0x12ab;

Если возникает какая-то неопределенность относительно того, имеет ли целое значение тип int, uint, long или ulong, то по умолчанию принимается int. Чтобы явно специфицировать, какой другой целочисленный тип должно иметь значение, к числу можно добавлять следующие символы:

uint ui = 1234U; long l = 1234L; ulong ul = 1234UL;

U и L можно также указывать в нижнем регистре, хотя строчную L легко зрительно спутать с цифрой 1 (единица).

Типы с плавающей точкой

Типы с плавающей точкой позволяют представлять числа с дробной частью. В C# имеются две разновидности типов данных с плавающей точкой: float и double. Они представляют числовые значения с одинарной и двойной точностью соответственно. Так, разрядность типа float составляет 32 бита, что приближенно соответствует диапазону представления чисел от 5E-45 до 3,4E+38. А разрядность типа double составляет 64 бита, что приближенно соответствует диапазону представления чисел от 5E-324 до 1,7Е+308.

Тип данных float предназначен для меньших значений с плавающей точкой, для которых требуется меньшая точность. Тип данных double больше, чем float, и предлагает более высокую степень точности (15 разрядов).

Если нецелочисленное значение жестко кодируется в исходном тексте (например, 12.3), то обычно компилятор предполагает, что подразумевается значение типа double. Если значение необходимо специфицировать как float, потребуется добавить к нему символ F (или f):

float f = 12.3F;

Десятичный тип данных

Для представления чисел с плавающей точкой высокой точности предусмотрен также десятичный тип decimal, который предназначен для применения в финансовых расчетах. Этот тип имеет разрядность 128 бит для представления числовых значений в пределах от 1Е-28 до 7,9Е+28. Вам, вероятно, известно, что для обычных арифметических вычислений с плавающей точкой характерны ошибки округления десятичных значений. Эти ошибки исключаются при использовании типа decimal, который позволяет представить числа с точностью до 28 (а иногда и 29) десятичных разрядов. Благодаря тому что этот тип данных способен представлять десятичные значения без ошибок округления, он особенно удобен для расчетов, связанных с финансами:

using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ConsoleApplication1 < class Program < static void Main(string[] args) < // *** Расчет стоимости капиталовложения с *** // *** фиксированной нормой прибыли*** decimal money, percent; int i; const byte years = 15; money = 1000.0m; percent = 0.045m; for (i = 1; i Console.WriteLine("Общий доход за лет: $$",years,money); Console.ReadLine(); > > > 

Результатом работы данной программы будет:

Использование типа decimal

Символы

В C# символы представлены не 8-разрядным кодом, как во многих других языках программирования, например С++, а 16-разрядным кодом, который называется юникодом (Unicode). В юникоде набор символов представлен настолько широко, что он охватывает символы практически из всех естественных языков на свете. Если для многих естественных языков, в том числе английского, французского и немецкого, характерны относительно небольшие алфавиты, то в ряде других языков, например китайском, употребляются довольно обширные наборы символов, которые нельзя представить 8-разрядным кодом. Для преодоления этого ограничения в C# определен тип char, представляющий 16-разрядные значения без знака в пределах от 0 до 65 535. При этом стандартный набор символов в 8-разрядном коде ASCII является подмножеством юникода в пределах от 0 до 127. Следовательно, символы в коде ASCII по-прежнему остаются действительными в C#.

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

char ch; ch = 'Z';

Несмотря на то что тип char определен в C# как целочисленный, его не следует путать со всеми остальными целочисленными типами. Дело в том, что в C# отсутствует автоматическое преобразование символьных значений в целочисленные и обратно. Например, следующий фрагмент кода содержит ошибку:

char ch; ch = 8; // ошибка, не выйдет

Наравне с представлением char как символьных литералов, их можно представлять как 4-разрядные шестнадцатеричные значения Unicode (например, ‘\u0041’), целочисленные значения с приведением (например, (char) 65) или же шестнадцатеричные значения (например, ‘\x0041’). Кроме того, они могут быть представлены в виде управляющих последовательностей.

Логический тип данных

Тип bool представляет два логических значения: «истина» и «ложь». Эти логические значения обозначаются в C# зарезервированными словами true и false соответственно. Следовательно, переменная или выражение типа bool будет принимать одно из этих логических значений. Кроме того, в C# не определено взаимное преобразование логических и целых значений. Например, 1 не преобразуется в значение true, а 0 — в значение false.

К какому типу относятся методы в C#? Reference type or Value type?

Все классы, структуры, массивы и делегаты — ссылочный тип. Value Type включают большинство встроенных типов (в частности, все числовые типы, тип char и тип bool), а также пользовательские типы struct и enum. К какому типу относятся методы? Определяется по возвращаемому значению я так понимаю? Если void, то null, если int, то Value Type, right?

Отслеживать
задан 4 ноя 2021 в 21:01
Michael Clifford Michael Clifford
331 1 1 серебряный знак 11 11 бронзовых знаков
Методы вовсе не являются объектами, поэтому не обладают типом.
4 ноя 2021 в 21:02
Да, а структуры являются значимыми типами (value type), а не ссылочными.
4 ноя 2021 в 21:04
@VladD да, спасибо, структуры значимый тип, запутался маленько, спасибо за ответ
5 ноя 2021 в 10:52

0

Сортировка: Сброс на вариант по умолчанию

Знаете кого-то, кто может ответить? Поделитесь ссылкой на этот вопрос по почте, через Твиттер или Facebook.

    Важное на Мете
Похожие

Подписаться на ленту

Лента вопроса

Для подписки на ленту скопируйте и вставьте эту ссылку в вашу программу для чтения RSS.

Дизайн сайта / логотип © 2024 Stack Exchange Inc; пользовательские материалы лицензированы в соответствии с CC BY-SA . rev 2024.3.1.5619

Value Types and Reference Types

В Visual Basic существует два типа типов: ссылочные типы и типы значений. В переменных ссылочных типов хранятся ссылки на их данные (объекты), а переменные типа значений содержат свои данные непосредственно. Две переменные ссылочного типа могут ссылаться на один и тот же объект, поэтому операции над одной переменной могут затрагивать объект, на который ссылается другая переменная. При использовании типов значений каждая переменная имеет собственную копию данных, и операции с одной переменной не могут влиять на другую (за исключением модификатора ByRef для параметров).

Типы значений

Тип данных — это тип значения , если он содержит данные в пределах собственного выделения памяти. Типы значений включают следующие:

  • Все числовые типы данных
  • Boolean , Char и Date .
  • Все структуры, даже если их члены являются ссылочными типами
  • Перечисления, так как их базовый тип всегда SByte имеет значение , Short , Integer , Long , Byte , UShort , UInteger или ULong

Каждая структура является типом значения, даже если она содержит элементы ссылочного типа. По этой причине типы значений, такие как Char и Integer , реализуются платформа .NET Framework структурами.

Тип значения можно объявить с помощью зарезервированного ключевое слово, например Decimal . Вы также можете использовать ключевое слово для инициализации New типа значения. Это особенно полезно, если тип имеет конструктор, принимаюющий параметры. Примером этого является Decimal(Int32, Int32, Int32, Boolean, Byte) конструктор, который создает новое Decimal значение из предоставленных частей.

Ссылочные типы

Ссылочный тип хранит ссылку на свои данные. К ссылочным типам относятся следующие:

  • String
  • Все массивы, даже если их элементы являются типами значений
  • Типы классов, например Form
  • Делегаты

Класс является ссылочным типом. Обратите внимание, что каждый массив является ссылочным типом, даже если его члены являются типами значений.

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

Dim totals() As Single = New Single(8) <> 

Элементы, которые не являются типами

Следующие элементы программирования не квалифицируются как типы, так как их нельзя указать в качестве типа данных для объявленного элемента:

  • Пространства имен
  • Модули
  • События
  • Свойства и процедуры
  • Переменные, константы и поля

Работа с типом данных объекта

Переменной Object типа данных можно назначить ссылочный тип или тип значения. Переменная Object всегда содержит ссылку на данные, а не сами данные. Однако если присвоить Object переменной тип значения, она будет вести себя так, как если бы она хранит собственные данные. Дополнительные сведения см. в разделе Тип данных объекта.

Чтобы узнать, является ли переменная Object ссылочным типом или типом значения, можно передать IsReference ее в метод в Information классе Microsoft.VisualBasic пространства имен. Information.IsReference возвращает значение True , если содержимое переменной Object представляет ссылочный тип.

См. также раздел

  • Типы значений, допускающие значение NULL
  • Преобразование типов в Visual Basic
  • Оператор Structure
  • Эффективное использование типов данных
  • Object Data Type
  • Типы данных

Совместная работа с нами на GitHub

Источник этого содержимого можно найти на GitHub, где также можно создавать и просматривать проблемы и запросы на вытягивание. Дополнительные сведения см. в нашем руководстве для участников.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *