Читайте также:
|
|
В CLR каждый объект прямо или косвенно является производным от System.Object.
Открытые методы:
Equals Возвращает true, если два объекта имеют одинаковые значения.
GetHashCode В озвращает хеш-код для значения данного объекта. Этот метод следует переопределить, если объекты типа используются в качестве ключа в хеш-таблице. Очень неудачно, что этот метод определен в Object, потому что большинство типов не служат ключами в хеш-таблице; этот метод уместнее было бы определить в интерфейсе.
ToString По умолчанию возвращает полное имя типа (this.GetTypeQutlName). На практике этот метод переопределяют, чтобы он возвращал объект String, содержащий состояние объекта в виде строки. Например, переопределенные методы для таких фундаментальных типов, как Boolean и Int32, возвращают значения объектов в строковом виде. Кроме того, переопределение метода часто применяют при отладке; вызов такого метода позволяет получить строку, содержащую значения полей объекта. Считается, что ToString «знает о Culturelnfo, связанном с вызывающим потоком.
GetType Возвращает экземпляр объекта, производного от type, который идентифицирует тип объекта, вызвавшего GetType. Возвращаемый объект Туре может использоваться с классами, реализующими отражение для получения информации о типе в виде метаданных Метод GetType невиртуальный, его нельзя переопределить, поэтому классу не удастся исказить сведения о своем типе. Таков механизм обеспечения безопасности типов.
Защищенные методы:
MemberwiseClone Этот невиртуальный метод создает новый экземпляр типа и присваивает полям нового объекта соответствующие значения объекта this. Возвращается ссылка на созданный экземпляр
Finalize Этот виртуальный метод вызывается, когда сборщик мусора определяет, что объект является мусором, но до возвращения занятой объектом памяти в кучу. В типах, требующих очистки при сборке мусора, следует переопределить этот метод.
CLR поддерживает две разновидности типов: ссылочные (reference types) и значимые (value types). Большинство типов в FCL — ссылочные, но программисты чаще всего используют значимые. Память для ссылочных типов всегда выделяется из управляемой кучи, а оператор С# new возвращает адрес в памяти, где размещается сам объект. При работе с ссылочными типами имейте в виду следующие обстоятельства, относящиеся к производительности приложения:
■ память для ссылочных типов всегда выделяется из управляемой кучи;
■ каждый объект, размещаемый в куче, имеет некоторые дополнительные члены, подлежащие инициализации;
■ незанятые полезной информацией байты объекта обнуляются (это касается полей);
■ размещение объекта в управляемой куче со временем инициирует сборку мусора.
Если бы все типы были ссылочными, эффективность приложения резко упала бы. Представьте, насколько замедлится выполнение приложения, если при каждом обращении к значению типа Int32 будет выделяться память! Поэтому, чтобы ускорить обработку простых, часто используемых типов, CLR предлагает «облегченные» типы — значимые. Экземпляры этих типов обычно размещаются в стеке потока (хотя они могут быть встроены и в объект ссылочного типа). В представляющей экземпляр переменной нет указателя на экземпляр; поля экземпляра размещаются в самой переменной. Поскольку переменная содержит поля экземпляра, то для работы с экземпляром не нужно выполнять разыменовывание (dereference) экземпляра. Благодаря тому, что экземпляры значимых типов не обрабатываются сборщиком мусора, уменьшается интенсивность работы с управляемой кучей и сокращается количество наборов (collections), требуемых приложению на протяжении его существования.
В документации по.NET Framework можно сразу увидеть, какие типы относят к ссылочным, а какие — к значимым. Если тип называют классом (class), речь идет о ссылочном типе. Так, классы SystemObject, SystemException, SystemJOfileStream
и SystemRandom — это ссылочные типы. В свою очередь значимые типы в документации называют структурами (structure) и перечислениями (enumeration). Например, структуры SystemInt32, System Boolean, SystemDecimal, System.TimeSpan и перечисления System DayOFWeek, System IOFileAttributes и SystemDrawingFontStyle являются значимыми типами.
При внимательном знакомстве с документацией можно заметить, что все структуры являются прямыми потомками абстрактною типа SystemValueType, который в свою очередь является производным от тина System.Object. По умолчанию все значимые типы должны быть производными от SystemValueType. Все перечисления являются производными от типа SystemEnum, производного от SystemValueType. CLR и языки программирования по-разному интерпретируют перечисления.
При определении собственного значимого типа нельзя выбрать произвольный базовый тип, однако значимый тип может реализовать один или несколько выбранных вами интерфейсов. Кроме того, в CLR значимый тип является изолированным, то есть не может служить базовым типом для какого-либо другого ссылочного или значимого типа. Поэтому, например, нельзя в описании нового типа указать в качестве базовых Boolean, Char, Int32, Uint64, Single, Double, Decimal и т. д.
■ Объекты значимого типа существуют в двух формах: неупакованной (unboxed) и упакованной (boxed). Ссылочные типы бывают только в упакованной форме.
■ Значимые типы являются производными от System.ValueType. Этот тип имеет те же методы, что и System.Object. Однако SystemValueType переопределяет метод Equals, который возвращает true, если значения полей в обоих объектах совпадают. Кроме того, в SystemValueType переопределен метод GetHashCode, который создает значение хеш-кода с помощью алгоритма, учитывающего значения полей экземпляра объекта. Из-за проблем с производительностью в реализации по умолчанию, определяя собственные значимые типы значений, надо переопределить и написать свою реализацию методов Equals и GetHashCode.
■ Поскольку в объявлении нового значимого или ссылочного типа нельзя указывать значимый тип в качестве базового класса, то создавать в значимом типе новые виртуальные методы нельзя. Методы не могут быть абстрактными и неявно являются изолированными (то есть их нельзя переопределить).
■ Переменные ссылочного типа содержат адреса объектов в куче. Когда переменная ссылочного типа создается, ей по умолчанию присваивается null, то есть в этот момент она не указывает на действительный объект. Попытка задействовать переменную с таким значением приведет к генерации исключения Null-ReferenceException. В то же время в переменной значимого типа всегда содержится некое значение соответствующего типа, а при инициализации всем членам этого типа присваивается 0. Поскольку переменная значимого типа не является указателем, при обращении к значимому типу исключение NullRefe-renceException возникнуть не может. CLR поддерживает понятие особого вида значимого типа, допускающего присваивание null, (mailable types).
■ Когда переменной значимого типа присваивается другая переменная значимого типа, выполняется копирование всех ее полей. Когда переменной ссылочного типа присваивается переменная ссылочного типа, копируется только ее адрес.
■ Вследствие сказанного в предыдущем абзаце, несколько переменных ссылочного типа могут ссылаться на один объект в куче, благодаря чему, работая с одной переменной, можно изменить объект, на который ссылается другая переменная. С другой стороны, каждая переменная значимого типа имеет собственную копию данных «объекта», и операции с одной переменной значимого типа не повлияют на другую переменную.
■ Так как неупакованные значимые типы не размещаются в куче, память, отведенная для них, освобождается сразу при возвращении управления методом, в котором описан экземпляр этого типа. Это значит, что экземпляр значимого типа не получает уведомления (через метод Finalize), когда его память освобождается.
Дата добавления: 2015-01-30; просмотров: 145 | Поможем написать вашу работу | Нарушение авторских прав |