2010-08-17 1 views
25

Я попытался создать ValueType.System.ValueType Понимание

Я понимаю, что создание структуры мне поможет.

Я также попытался получить тип из System.ValueType, который является абстрактным классом.

Но я получил сообщение об ошибке компилятора «.. не может извлечь из специального класса System.ValueType»

Когда я вижу метаданные ValueType, это выглядит обычный абстрактный класс.

  1. Что сделало его особенным?

  2. Это компилятор C#, который воспринимает его как особый?

  3. Если да, рекомендуется ли оно, как правило, для конструкции компилятора? Я имею в виду, это часть Common Language Specification?

+1

Для действительно хорошего понимания того, как наилучшим образом создавать типы значений, проверка Эффективный C# (2-е изд.), Билл Вагнер; особенно в пункте 20. В нем также содержится много полезной информации. –

+0

Dupe: [why-cant-i-outive-from-system-enum-abstract-class] (http://stackoverflow.com/questions/2324667/why-cant-i-derive-from-system-enum-abstract -класс) – nawfal

+1

Очень красивый и понятный вопрос. Экономит время чтения. Я призываю всех четко задать вопрос. Благодарю. –

ответ

26

ValueType - небольшая белая ложь.

Все типы значений являются встроенными численными типами (int, long, byte), char, enums и structs.

Это означает, что они имеют разные концепции идентичности и эквивалентности типов объектов. Если я делаю x = y, а x и y являются ссылочными типами, то x и y теперь указывают на один и тот же объект. Однако, если я делаю x = y, а x и y - типы значений, тогда x и y теперь представляют собой два совершенно разных объекта, которые оказываются идентичными. (Это также отражено в == и Equals, хотя это можно переопределить).

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

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

Конечно, это означает, что вы можете делать вещи с помощью int, которые имеют смысл делать только в System.Object, поэтому, когда вы это сделаете, int «помещается в коробку» и может быть снова «распакован».

Это замечательно, но что, если мы хотим сделать что-то конкретное для типов значений? Более того, что, если дизайнеры CLR сделали (в частности, они хотели получить GetHashCode для типов значений, связанных с эквивалентной стоимостью, описанной выше, а не эквивалентностью, основанной на идентификаторах, которые имеют объекты)?

Для этого у нас есть ValueType. Система рассматривает все типы значений как наследующие от этого класса, который, в свою очередь, наследует от Object. Enum, в свою очередь, наследует от типа значения и всех типов перечисления, наследуемых от него, что позволяет использовать некоторые общие функции во всех перечислениях.

Итак, если вы когда-либо захотите обработать суперкласс всех типов значений, используйте ValueType, но если вы хотите фактически создать тип значения, создайте структуру или перечисление, если это необходимо.


Общий Тип системы Объяснение:

структура является типом значения, что происходит неявно из System.ValueType, который, в свою очередь, является производным от System.Object. Структура очень полезна для представления значений, требования к памяти которых малы, и для передачи значений в виде параметров по значению методам, которые имеют строго типизированные параметры. В библиотеке классов .NET Framework все примитивные типы данных (Boolean, Byte, Char, DateTime, Decimal, Double, Int16, Int32, Int64, SByte, Single, UInt16, UInt32 и UInt64) определяются как структуры.

Как и классы, структуры определяют как данные (поля структуры), так и операции, которые могут выполняться над этими данными (методы структуры). Это означает, что вы можете вызывать методы для структур, включая виртуальные методы, определенные в классах System.Object и System.ValueType, и любые методы, определенные для самого типа значения. Другими словами, структуры могут иметь поля, свойства и события, а также статические и нестатические методы. Вы можете создавать экземпляры структур, передавать их в качестве параметров, хранить их как локальные переменные или хранить их в поле другого типа значения или ссылочного типа. Структуры также могут реализовывать интерфейсы.

Типы значений также отличаются от классов в нескольких отношениях. Во-первых, хотя они неявно наследуются от System.ValueType, они не могут напрямую наследоваться от любого типа. Аналогично, все типы значений запечатываются, а это означает, что из них не может быть выведен другой тип. Они также не требуют конструкторов.

Для каждого типа значений общая среда выполнения языков предоставляет соответствующий тип в виде бокса, который является классом, который имеет такое же состояние и поведение, что и тип значения. Экземпляр типа значения помещается в бокс, когда он передается методу, который принимает параметр типа System.Object.Он распаковывается (то есть преобразуется из экземпляра класса обратно в экземпляр типа значения), когда элемент управления возвращается из вызова метода, который принимает тип значения в качестве параметра для ссылки. Некоторые языки требуют, чтобы вы использовали специальный синтаксис, когда требуется тип boxed; другие автоматически используют коробчатый тип, когда это необходимо. Когда вы определяете тип значения, вы определяете как коробку, так и тип unboxed.

Странность ValueType заключается в том, чтобы позволить, чтобы это произошло.

+1

Благодарю вас за разъяснения. Но на самом деле, как они сделали это особенным, мой вопрос все еще. System.ValueType не является запечатанным и абстрактным. Поэтому он должен иметь право быть родительским классом.(Так было сделано для Enum, Int32 и т. Д.) Если компилятор C# относится к нему особым образом, он также должен быть на других языках (VB.Net, J #). Но я не вижу заметки в Microsoft Common Language Specification. http://msdn.microsoft.com/en-us/library/12a7a7h3.aspx. Поэтому я все еще думаю, что есть что-то скрытое, и это имеет другое объяснение. – SaravananArumugam

+0

@Saravanandss Добавлено объяснение из документальной системы Common Type выше. Не то, чтобы он настаивал на том, что типы значений * неявно * вытекают из System.ValueType, а также настаивают на том, что они не могут извлечь из чего-либо. Решение о сокращении сделано, если вы описываете странность. –

+2

Похож на утку, шарлатан, как утку, плавает как утка, это утка. Но это не так. –

1

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

см MSDN знать больше

+0

Любой незапечатанный класс должен быть выводимым. Но System.ValueType не является закрытым классом. И он говорит сам по себе особый класс. Что делает его особенным? это мой вопрос – SaravananArumugam

+1

@Saravanandss CLR. NET дозировать его особенным. – Arseny

3

Структуры являются типами значений. Типы значений являются особыми, потому что они выделяются в стеке, а не в кучу. Чтобы «наследовать» из ValueType, вы должны создать структуру.

+0

Структура - тип значения - это теория. Но мой вопрос был другим: что делает особенностью System.ValueType? Его не запечатанный класс, но он не позволяет выводить. – SaravananArumugam

+1

@Saravanandss, «структура - тип ценности» - это факт, а не теория. Это действительно так. –

1

C# не разрешает типы значений наследовать от других классов. Типы значений (struct) могут реализовывать интерфейсы.

0
  1. A 'class' расширяет 'System.Object', 'struct' расширяет 'System.ValueType'. Если вы можете сделать класс расширенным «System.ValueType», то ключевое слово «struct» не будет многозначительно.

  2. Да

  3. Да. Должен быть только один способ выполнить любую данную вещь. Как только будут предоставлены два способа сделать что-то, вы просто сделаете все более сложным. Главное правило.

+0

Необходимо иметь в виду, что все в .NET в конечном итоге является System.Object. – Michael

+0

Я не согласен с этим. В мире программирования есть много способов сделать что-то. Например, если (a == b) c = 0; else c = 1; эквивалентно c = (a == b)? 0: 1; И Nullable s = null; Int32? s = null; равны. Нет никакого правила говорить, что должен быть только один способ добиться чего-то. – SaravananArumugam

+0

Всегда должно быть как можно больше способов сделать что-то. Всегда должно быть как можно меньше возможностей, чтобы вещи делались для вас. Оба этих бесплатных разработчика. –

2

Невозможность получения значения ValueType специфична для компилятора C#. Если мы посмотрим на управляемый код C++:

value class Foo {}; 
value class Foo : System::ValueType {}; 

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

ref class Foo : System::ValueType {}; 

Даст C3050 ошибка: класс ссылок не может наследовать от 'System :: ValueType'.
Не знаете, что позволяют другие компиляторы.

Если вы хотите получить значение ValueType в C#, используйте struct, а не class, и компилятор позаботится об этом.

0

Это то, что меня озадачивает ... Enum происходит от ValueType. Это заставляет меня думать, что это просто ограничение компилятора.

[Serializable, ComVisible(true)] 
public abstract class Enum : ValueType, IComparable, IFormattable, IConvertible 
{ 
    ... 
} 
+1

В некоторых контекстах среда выполнения будет обрабатывать типы по-разному в зависимости от того, были ли они получены из «ValueType». Если компилятор позволил создать класс, который был получен из «ValueType» и не содержал никакого кода, такой класс будет вести себя как структура. Если класс действительно включал код, такой код, скорее всего, не сработает, потому что структуры и классы получают доступ к этому «другому»; если компилятор не знал, что 'this' является структурой, он будет генерировать неправильный код для доступа к нему. – supercat

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