Сдам Сам

ПОЛЕЗНОЕ


КАТЕГОРИИ







Public sealed class TestForSomeType





{

Void TestFunctionForSomeType()

{

int i=SomeType.SomeConstant; /* можно: константа принадлежит

типу */

//i = SomeType.GetConstant(); /* Нельзя обращаться к

экземплярной (нестатической) функции */

SomeType st = new SomeType();

// i=st.SomeConstant; /* нельзя: константа принадлежит типу,

но не объекту*/

i=st.GetConstant(); // можно

String s="SomePar";

i = st[s]; // чтение параметризованного свойства

}

}

Видимость типа

При определении типа с видимостью в рамках файла, а не другого типа, его можно сделать открытым {public) или внутренним (internal). Открытый тип доступен любому коду любой сборки. Внутренний тип доступен только из сборки, где он определен. По умолчанию компилятор С# делает тип внутренним. Вот несколько примеров:

using System;

// Это открытый тип; он доступен из любой сборки

public class ThisIsAPublicType {... }

// Это внутренний тип; он доступен только из собственной сборки

internal class ThisIsAnlnternalType {... }

// Это внутренний тип, так как модификатор доступа не указан явно

class ThisIsAlsoAnlnternalType {... }

 

Дружественные сборки – см. [11].

 

Доступ к членам

При определении члена типа (в том числе вложенного) можно указать модификатор доступа к члену. Модификаторы определяют, на какие члены можно ссылаться из кода. В CLR определен свой набор возможных модификаторов доступа, но в каждом языке программирования существует свой синтаксис и термины.

Например, термин Assembly в CLR указывает, что член доступен изнутри сборки, тогда как в С# для этого используется internal.

В табл. 5.1 приведены шесть модификаторов доступа, определяющие уровень ограничения — от максимального {Private) до минимального {Public).

 

Табл. 5.1. Модификаторы доступа к члену

Термин CLR Термин С# Описание
Private(Закрытый) private Доступен только методам в определяющем типе и вложенных в него типах
Family(Родовой) protected Доступен только методам в определяющем типе (и вложенных в него типах) или одном из его производных типов независимо от сборки
Family and Assembly(Родовой и Сборочный) (не поддерживается) Доступен только методам в определяющем типе (и вложенных в него типах) и производных типах в определяющей сборке
Assembly(Сборочный) internal Доступен только методам в определяющей сборке
Family or Assembly(Родовой или Сборочный) protected internal Доступен только методам вложенного типа, производного типа (независимо от сборки) и любым методам определяющей сборки
Public(Открытый) public Доступен всем методам во всех сборках

 

Разумеется, доступ к члену можно получить, только если он определен в видимом типе. Например, если в сборке А определен внутренний тип, имеющий открытый метод, то код сборки Б не сможет вызвать открытый метод, поскольку внутренний тип сборки А не доступен из Б.

В процессе компиляции кода компилятор языка проверяет корректность обращения кода к типам и членам. Обнаружив некорректную ссылку на какие-либо типы или члены, компилятор информирует об ошибке. Помимо этого, во время выполнения JIT-компилятор тоже проверяет корректность обращения к полям и методам при компиляции IL-кода в процессорные команды. Например, обнаружив код, неправильно пытающийся обратиться к закрытому полю или методу, JIT-компилятор генерирует исключение FieldAccessException или MethodAccessException соответственно.

Верификация IL-кода гарантирует правильность обработки модификаторов доступа к членам в период выполнения, даже если компилятор языка проигнорировал проверку доступа. Другая, более вероятная возможность заключается в компиляции кода, обращающегося к открытому члену другого типа (другой сборки); если в период выполнения загрузится другая версия сборки, где модификатор доступа открытого члена заменен защищенным (protected) или закрытым, верификация обеспечит корректное управление доступом.

Если не указать явно модификатор доступа, компилятор С# обычно (но не всегда) выберет по умолчанию закрытый — наиболее строгий из всех. CLR требует, чтобы все члены интерфейсного типа были открытыми. Поэтому компилятор С# запрещает программисту явно указывать модификаторы доступа к членам интерфейса, просто делая все члены открытыми.

Примечание. Подробнее о правилах применения в С# модификаторов доступа к типам и членам, а также о том, какие модификаторы С# выбирает по умолчанию в зависимости от контекста объявления, см. в разделе «Declared Accessibility» спецификации языка С#.

 

Более того, как видно из таблицы, в CLR есть модификатор доступа родовой и сборочный. Но разработчики С# сочли этот атрибут лишним и не включили в язык С#.

Если в производном типе переопределяется член базового типа, компилятор С# требует, чтобы у членов базового и производного типа был одинаковый модификатор доступа. То есть, если член базового класса является защищенным, то и член производного класса также должен быть защищенным. Однако это ограничение языка С#, а не CLR. При наследовании базовому классу CLR позволяет понижать, но не повышать уровень доступа к члену. Например, защищенный метод базового класса можно переопределить в производном классе как открытый, но только не как закрытый. Это необходимо, чтобы пользователь производного типа всегда мог получить доступ к методу базового класса путем приведения к базовому типу. Если бы CLR разрешала накладывать более жесткие ограничения на доступ к методу в производном типе, она выдавала бы желаемое за действительное. (Не совсем понятный абзац – надо проверять и уточнять (ОВН)).

Статические классы

Существуют классы, не предназначенные для создания экземпляров, например Console, Math, Environment и ThreadPool. У этих классов есть только статические методы. В сущности, такие классы существуют лишь для группировки логически связанных членов. Например, класс Math объединяет методы, выполняющие математические операции. В С# такие классы определяются с ключевым словом static. Его разрешается применять только к классам, но не структурам (значимым типам), поскольку CLR всегда разрешает создавать экземпляры значимых типов, и нет способа обойти это ограничение.

Компилятор налагает на статический класс ряд ограничений.

§ Класс должен быть прямым потомком System.Object — наследование любому другому базовому классу лишено смысла, поскольку наследование применимо только к объектам, а создать экземпляр статического класса невозможно.

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

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

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

 

Вот пример статического класса, в котором определены статические члены; сам по себе класс не представляет практического интереса.

using System;

public static class AStaticClass

{

public static void AStaticMethod() { }







Система охраняемых территорий в США Изучение особо охраняемых природных территорий(ООПТ) США представляет особый интерес по многим причинам...

Что будет с Землей, если ось ее сместится на 6666 км? Что будет с Землей? - задался я вопросом...

Что делает отдел по эксплуатации и сопровождению ИС? Отвечает за сохранность данных (расписания копирования, копирование и пр.)...

ЧТО ПРОИСХОДИТ, КОГДА МЫ ССОРИМСЯ Не понимая различий, существующих между мужчинами и женщинами, очень легко довести дело до ссоры...





Не нашли то, что искали? Воспользуйтесь поиском гугл на сайте:


©2015- 2024 zdamsam.ru Размещенные материалы защищены законодательством РФ.