Поэтому требование указывать этот параметр позволяет значительно повысить производительность компиляции. Аналогично, при компиляции с параметром C# t:module модуля (в противоположность сборке), который должен стать частью дружественной сборки, необходимо также использовать параметр moduleassemblyname:строка компилятора C#. Последний параметр говорит компилятору, к какой сборке будет относиться модуль, чтобы тот разрешил коду этого модуля обращаться к внутренним типам другой сборки. ГЛАВА 6 Основные сведения о членах и типах 149 Внимание! Дружественные сборки следует использовать только в сборках, поставляемых в одно время или, лучше всего, вместе. Взаимозависимость дружественных сборок настолько высока, что разнесение поставки по времени практически наверняка вызовет проблемы с совместимостью. Если сборки все же нужно поставлять в разное время, следует решить проблему созданием открытых классов, доступных из любой сборки, но ограничить доступ посредством LinkDemand, запрашивая разрешение StrongNameIdentityPermission. Доступ к членам При определении члена типа (в том числе вложенного) можно указать модификатор доступа к члену. Модификаторы определяют, на какие члены можно ссылаться из кода. В CLR определен свой набор возможных модификаторов доступа, но в каждом языке программирования существует свой синтаксис и термины. Например, термин Assembly в CLR указывает, что член доступен изнутри сборки, тогда как в C# для этого используется internal. В табл. 6-1 приведены шесть модификаторов доступа, определяющие уровень ограничения от максимального (Private) до минимального (Public). Табл. 6-1. Модификаторы доступа к члену Термин CLR Термин C# Описание Private (Закрытый) private Доступен только методам в определяющем типе и вложенных в него типах Family (Родовой) protected Доступен только методам в определяющем типе (и вложенных в него типах) или одном из его производных типов независимо от сборки Family and Assembly (Родовой и Сборочный) (не поддерживается) Доступен только методам в определяющем типе (и вложенных в него типах) и производных типах в определяющей сборке Assembly (Сборочный) internal Доступен только методам в определяющей сборке Family or Assembly (Родовой или Сборочный) protected internal Доступен только методам вложенного типа, производного типа (независимо от сборки) и любым методам определяющей сборки Public (Открытый) public Доступен всем методам во всех сборках Разумеется, доступ к члену можно получить, только если он определен в видимом типе. Например, если в сборке А определен внутренний тип, имеющий открытый метод, то код сборки Б не сможет вызвать открытый метод, поскольку внутренний тип сборки А не доступен из Б. В процессе компиляции кода компилятор языка проверяет корректность обращения кода к типам и членам. Обнаружив некорректную ссылку на какие-либо типы или члены, компилятор информирует об ошибке. Помимо этого, во время выполнения JIT-компилятор тоже проверяет корректность обращения к полям и методам при компиляции IL-кода в процессорные команды. Например, обнаружив код, неправильно пытающийся обратиться к закрытому полю или методу, JIT-компилятор генерирует исключение FieldAccessException или MethodAccessException соответственно. Часть III Проектирование типов Верификация IL-кода гарантирует правильность обработки модификаторов доступа к членам в период выполнения, даже если компилятор языка проигнорировал проверку доступа. Другая, более вероятная возможность заключается в компиляции кода, обращающегося к открытому члену другого типа (другой сборки); если в период выполнения загрузится другая версия сборки, где модификатор доступа открытого члена заменен защищенным (protected) или закрытым (private), верификация обеспечит корректное управление доступом. Если не указать явно модификатор доступа, компилятор C# обычно (но не всегда) выберет по умолчанию закрытый наиболее строгий из всех. CLR требует, чтобы все члены интерфейсного типа были открытыми. Поэтому компилятор C# запрещает программисту явно указывать модификаторы доступа к членам интерфейса, просто делая все члены открытыми. Примечание Подробнее о правилах применения в C# модификаторов доступа к типам и членам, а также о том, какие модификаторы C# выбирает по умолчанию в зависимости от контекста объявления, см. в разделе Declared Accessibility спецификации языка C#.