- •Спецификация языка
- •1. Введение 1
- •2. Лексическая структура 38
- •3. Основные принципы 61
- •4. Типы 89
- •5. Переменные 107
- •6. Преобразования 126
- •7. Выражения 151
- •8. Операторы языка 265
- •9. Пространства имен 298
- •10. Классы 311
- •11. Структуры 416
- •12. Массивы 429
- •13. Интерфейсы 435
- •18. Небезопасный код 490
- •1.Введение
- •1.1Программа «Hello world»
- •1.2Структура программы
- •1.3Типы и переменные
- •1.4Выражения
- •1.5Операторы языка
- •1.6Классы и объекты
- •1.6.1Члены
- •1.6.2Доступность
- •1.6.3Параметры типа
- •1.6.4Базовые классы
- •1.6.5Поля
- •1.6.6Методы
- •1.6.6.1Параметры
- •1.6.6.2Тело метода и локальные переменные
- •1.6.6.3Статические методы и методы экземпляров
- •1.6.6.4Виртуальные, переопределяющие и абстрактные методы
- •1.6.6.5Перегрузка метода
- •1.6.7Другие члены-функции
- •1.6.7.1Конструкторы
- •1.6.7.2Свойства
- •1.6.7.3Индексаторы
- •1.6.7.4События
- •1.6.7.5Операторы
- •1.6.7.6Деструкторы
- •1.7Структуры
- •1.8Массивы
- •1.9Интерфейсы
- •1.10Перечисления
- •1.11Делегаты
- •1.12Атрибуты
- •2.Лексическая структура
- •2.1Программы
- •2.2Грамматики
- •2.2.1Грамматическая нотация
- •2.2.2Лексика
- •2.2.3Синтаксическая грамматика
- •2.3Лексический анализ
- •2.3.1Знаки завершения строки
- •2.3.2Комментарии
- •2.3.3Пробел
- •2.4Маркеры
- •2.4.1Управляющие последовательности символов Юникода
- •2.4.2Идентификаторы
- •2.4.3Ключевые слова
- •2.4.4Литералы
- •2.4.4.1Логические литералы
- •2.4.4.2Целочисленные литералы
- •2.4.4.3Действительные литералы
- •2.4.4.4Символьные литералы
- •2.4.4.5Строковые литералы
- •2.4.4.6Литерал null
- •2.4.5Операторы и знаки пунктуации
- •2.5Препроцессорные директивы
- •2.5.1Символы условной компиляции
- •2.5.2Препроцессорные выражения
- •2.5.3Директивы объявлений
- •2.5.4Директивы условной компиляции
- •2.5.5Директивы диагностики
- •2.5.6Директивы областей
- •2.5.7Директивы строк
- •2.5.8Директивы pragma
- •2.5.8.1Директива pragma warning
- •3.Основные принципы
- •3.1Запуск приложения
- •3.2Завершение приложения
- •3.3Объявления
- •3.4Члены
- •3.4.1Члены пространства имен
- •3.4.2Члены структуры
- •3.4.3Члены перечисления
- •3.4.4Члены класса
- •3.5.1Объявленная доступность
- •3.5.2Домены доступности
- •3.5.3Защищенный доступ для членов экземпляров.
- •3.5.4Ограничения доступности
- •3.6Сигнатуры и перегрузка
- •3.7Области видимости
- •3.7.1Скрытие имени.
- •3.7.1.1Скрытие через вложение.
- •3.7.1.2Скрытие через наследование
- •3.8Имена пространств имен и типов
- •3.8.1Полные имена
- •3.9Автоматическое управление памятью
- •3.10Порядок выполнения
- •4.1Типы значений
- •4.1.2Конструкторы по умолчанию
- •4.1.3Типы структуры
- •4.1.4Простые типы
- •4.1.5Целые типы
- •4.1.6Типы с плавающей запятой
- •4.1.9Перечисляемые типы
- •4.1.10Обнуляемые типы
- •4.2Ссылочные типы
- •4.2.1Типы классов
- •4.2.2Тип объекта
- •4.2.3Динамический тип
- •4.3Упаковка и распаковка
- •4.3.1Преобразования упаковки
- •4.3.2Преобразования распаковки
- •4.4Сформированные типы
- •4.4.1Аргументы типа
- •4.4.2Открытые и закрытые типы
- •4.4.3Связанные и несвязанные типы
- •4.4.4Соблюдение ограничений
- •4.5Параметры типа
- •4.6Типы дерева выражений
- •4.7Динамический тип
- •5.Переменные
- •5.1Категории переменных
- •5.1.1Статические переменные
- •5.1.2Переменные экземпляра
- •5.1.2.1Переменные экземпляра в классах
- •5.1.2.2Переменные экземпляра в структурах
- •5.1.3Элементы массива
- •5.1.4Параметры по значению
- •5.1.5Параметры по ссылке
- •5.1.6Выходные параметры
- •5.1.7Локальные переменные
- •5.2Значения по умолчанию
- •5.3Определенное присваивание
- •5.3.1Переменные с начальным значением
- •5.3.2Переменные без начального значения
- •5.3.3Точные правила для выявления определенного присваивания
- •5.3.3.1Общие правила для операторов
- •5.3.3.2Операторы блока, операторы checked и unchecked
- •5.3.3.3Операторы-выражения
- •5.3.3.4Операторы объявления
- •5.3.3.5Операторы If
- •5.3.3.6Операторы switch
- •5.3.3.7Операторы while
- •5.3.3.8Операторы do
- •5.3.3.9Операторы for
- •5.3.3.10Операторы break, continue и goto
- •5.3.3.11Операторы throw
- •5.3.3.12Операторы return
- •5.3.3.13Операторы try-catch
- •5.3.3.14Операторы try-finally
- •5.3.3.15Операторы try-catch-finally
- •5.3.3.16Операторы foreach
- •5.3.3.17Операторы using
- •5.3.3.18Операторы lock
- •5.3.3.19Операторы yield
- •5.3.3.20Общие правила для простых выражений
- •5.3.3.21Общие правила для выражений с внедренными выражениями
- •5.3.3.22Выражения вызова и выражения создания объекта
- •5.3.3.23Простые выражения присваивания
- •5.3.3.24Выражения &&
- •5.3.3.25Выражения ||
- •5.3.3.26! Выражения !
- •5.3.3.27?? Выражения ??
- •5.3.3.28Выражения ?:
- •5.3.3.29Анонимные функции
- •5.4Ссылочные переменные
- •5.5Атомарность ссылок на переменные
- •6.Преобразования
- •6.1Неявные преобразования
- •6.1.1Преобразование идентификатора
- •6.1.2Неявные преобразования числовых типов
- •6.1.3Неявные преобразования перечисляемых типов
- •6.1.4Неявные преобразования обнуляемых типов
- •6.1.5Преобразования литерала null
- •6.1.6Неявные преобразования ссылочных типов
- •6.1.7Преобразования упаковки
- •6.1.8Неявные динамические преобразования
- •6.1.9Неявные преобразования выражений констант
- •6.1.10Неявные преобразования, включающие параметры типа
- •6.1.11Пользовательские неявные преобразования
- •6.1.12Преобразования анонимных функций и преобразования группы методов
- •6.2Явные преобразования
- •6.2.1Явные преобразования числовых типов
- •6.2.2Явные преобразования перечисляемых типов
- •6.2.3Явные преобразования обнуляемых типов
- •6.2.4Явные преобразования ссылочных типов
- •6.2.5Преобразования распаковки
- •6.2.6Неявные динамические преобразования
- •6.2.7Явные преобразования, включающие параметры типа
- •6.2.8Пользовательские явные преобразования
- •6.3Стандартные преобразования
- •6.3.1Стандартные неявные преобразования
- •6.3.2Стандартные явные преобразования
- •6.4Пользовательские преобразования
- •6.4.1Допустимые пользовательские преобразования
- •6.4.2Операторы преобразования с нулификацией
- •6.4.3Вычисление пользовательских преобразований
- •6.4.4Определенные пользователем неявные преобразования
- •6.4.5Определенные пользователем явные преобразования
- •6.5Преобразования анонимных функций
- •6.5.1Вычисление преобразования анонимной функции к типу делегата
- •6.5.2Вычисление преобразования анонимной функции к типу дерева выражений
- •6.5.3Пример реализации
- •6.6Преобразования группы методов
- •7.Выражения
- •7.1Классы выражений
- •7.1.1Значения выражений
- •7.2Статическая и динамическая привязка
- •7.2.1Время привязки
- •7.2.2Динамическая привязка
- •7.2.3Типы составных выражений
- •7.3Операторы
- •7.3.1Приоритет и ассоциативность операторов
- •7.3.2Перегрузка операторов
- •7.3.3Разрешение перегрузки унарных операторов
- •7.3.4Разрешение перегрузки бинарных операторов
- •7.3.5Пользовательские операторы-кандидаты
- •7.3.6Числовое расширение
- •7.3.6.1Числовое расширение унарных операторов
- •7.3.6.2Числовое расширение бинарных операторов
- •7.3.7Операторы с нулификацией
- •7.4Поиск членов
- •7.4.1Базовые типы
- •7.5Функции-члены
- •7.5.1Списки аргументов
- •7.5.1.1Соответствующие параметры
- •7.5.1.2Вычисление списков аргументов во время выполнения
- •7.5.2Вывод типа
- •7.5.2.1Первый этап
- •7.5.2.2Второй этап
- •7.5.2.3Типы ввода
- •7.5.2.4 Типы вывода
- •7.5.2.5Зависимость
- •7.5.2.6Вывод типа вывода
- •7.5.2.7Вывод явных типов параметров
- •7.5.2.8Точный вывод
- •7.5.2.9Вывод нижних границ
- •7.5.2.10Вывод по верхним границам
- •7.5.2.11Фиксирование
- •7.5.2.12Выведенный тип возвращаемого значения
- •7.5.2.13Вывод типа при преобразовании групп методов
- •7.5.2.14Поиск наиболее подходящего общего типа для набора выражений
- •7.5.3Разрешение перегрузки
- •7.5.3.1Применимая функция-член
- •7.5.3.2Более подходящая функция-член
- •7.5.3.3Лучшее преобразование из выражения
- •7.5.3.4Лучшее преобразование из типа
- •7.5.3.5Лучшая цель для преобразования
- •7.5.3.6Перегрузка в универсальных классах
- •7.5.4Проверка динамического разрешения перегрузки во время компиляции
- •7.5.5Вызов функции-члена
- •7.5.5.1Вызов в упакованных экземплярах
- •7.6Первичные выражения
- •7.6.1Литералы
- •7.6.2Простые имена
- •7.6.2.1Инвариантность значения в блоках
- •7.6.3Выражения со скобками
- •7.6.4Доступ к члену
- •7.6.4.1Идентичные простые имена и имена типов
- •7.6.4.2Грамматическая неоднозначность
- •7.6.5Выражения вызова
- •7.6.5.1Вызовы методов
- •7.6.5.2Вызовы методов расширения
- •7.6.5.3Вызовы делегатов
- •7.6.6Метод доступа к элементу
- •7.6.6.1Доступ к массиву
- •7.6.6.2Доступ к индексатору
- •7.6.7Доступ this
- •7.6.8Доступ base
- •7.6.9Постфиксные операторы инкремента и декремента
- •7.6.10Оператор new
- •7.6.10.1Выражения создания объектов
- •7.6.10.2Инициализаторы объектов
- •7.6.10.3Инициализаторы коллекции
- •7.6.10.4Выражения создания массива
- •7.6.10.5Выражения создания делегата
- •7.6.10.6Выражения создания анонимных объектов
- •7.6.11Оператор typeof
- •7.6.12Операторы checked и unchecked
- •7.6.13Выражения значения по умолчанию
- •7.6.14Выражения анонимного метода
- •7.7Унарные операторы
- •7.7.1Унарный оператор «плюс»
- •7.7.2Унарный оператор «минус»
- •7.7.3Оператор логического отрицания
- •7.7.4Оператор побитового дополнения
- •7.7.5Префиксные операторы инкремента и декремента
- •7.7.6Выражения приведения типа
- •7.8Арифметические операторы
- •7.8.1Оператор произведения
- •7.8.2Оператор деления
- •7.8.3Оператор остатка
- •7.8.4Оператор сложения
- •7.8.5Оператор вычитания
- •7.9Операторы сдвига
- •7.10Операторы отношения и проверки типа
- •7.10.1Операторы сравнения целых чисел
- •7.10.2Операторы сравнения чисел с плавающей запятой
- •7.10.3Операторы сравнения десятичных чисел
- •7.10.4Логические операторы равенства
- •7.10.5Операторы сравнения значений перечисления
- •7.10.6Операторы равенства значений ссылочного типа
- •7.10.7Операторы равенства строк
- •7.10.8Операторы равенства делегатов
- •7.10.9Операторы равенства и значение null
- •7.10.10Оператор is
- •7.10.11Оператор as
- •7.11Логические операторы
- •7.11.1Логические операторы для целых чисел
- •7.11.2Логические операторы для перечислений
- •7.11.3Логические операторы
- •7.11.4Обнуляемые логические операторы
- •7.12Условные логические операторы
- •7.12.1Логические условные операторы
- •7.12.2Пользовательские условные логические операторы
- •7.13Оператор слияния с null
- •7.14Условный оператор
- •7.15Выражения анонимных функций
- •7.15.1Сигнатуры анонимных функций
- •7.15.2Тела анонимных функций
- •7.15.3Разрешение перегрузки
- •7.15.4Анонимные функции и динамическая привязка
- •7.15.5Внешние переменные
- •7.15.5.1Захваченные внешние переменные
- •7.15.5.2Создание экземпляров локальных переменных
- •7.15.6Вычисление выражений анонимных функций
- •7.16Выражения запросов
- •7.16.1Неоднозначность в выражениях запросов
- •7.16.2Перевод выражений запросов
- •7.16.2.1Предложения select и groupby с продолжениями
- •7.16.2.2Явные типы переменных диапазона
- •7.16.2.3Выражения вырожденных запросов
- •7.16.2.4Предложения from, let, where, join и orderby
- •7.16.2.5Предложения select
- •7.16.2.6Предложения groupby
- •7.16.2.7Прозрачные идентификаторы
- •7.16.3Шаблон выражения запроса
- •7.17Операторы присваивания
- •7.17.1Простое присваивание
- •7.17.2Сложное присваивание
- •7.17.3Присваивание событий
- •7.18Выражение
- •7.19Константные выражения
- •7.20Логические выражения
- •8.Операторы языка
- •8.1Конечные точки и достижимость
- •8.2Блоки
- •8.2.1Списки операторов
- •8.3Пустой оператор
- •8.4Помеченные операторы
- •8.5Операторы объявления
- •8.5.1Объявления локальных переменных
- •8.5.2Объявления локальных констант
- •8.6Операторы-выражения
- •8.7Операторы выбора
- •8.7.1Оператор if
- •8.7.2Оператор switch
- •8.8Операторы итераций
- •8.8.1Оператор while
- •8.8.2Оператор do
- •8.8.3Оператор for
- •8.8.4Оператор foreach
- •8.9Операторы перехода
- •8.9.1Оператор break
- •8.9.2Оператор continue
- •8.9.3Оператор goto
- •8.9.4Оператор return
- •8.9.5Оператор throw
- •8.10Оператор try
- •8.11Операторы checked и unchecked
- •8.12Оператор lock
- •8.13Оператор using
- •8.14Оператор yield
- •9.Пространства имен
- •9.1Единицы компиляции
- •9.2Объявления пространства имен
- •9.3Внешние псевдонимы
- •9.4Директивы using
- •9.4.1Директивы using alias
- •9.4.2Директивы using namespace
- •9.5Члены пространства имен
- •9.6Объявления типов
- •9.7Квалификаторы псевдонима пространства имен
- •9.7.1Уникальность псевдонимов
- •10.Классы
- •10.1Объявления классов
- •10.1.1Модификаторы классов
- •10.1.1.1Абстрактные классы
- •10.1.1.2Запечатанные классы
- •10.1.1.3Статические классы
- •10.1.1.3.1Ссылки на типы статического класса
- •10.1.2Модификатор partial
- •10.1.3Параметры типа
- •10.1.4Спецификация базы класса
- •10.1.4.1Базовые классы
- •10.1.4.2Реализация интерфейсов
- •10.1.5Ограничения параметров типа
- •10.1.6Тело класса
- •10.2Разделяемые типы
- •10.2.1Атрибуты
- •10.2.2Модификаторы
- •10.2.3Параметры и ограничения типа
- •10.2.4Базовый класс
- •10.2.5Базовые интерфейсы
- •10.2.6Члены
- •10.2.7Разделяемые методы
- •10.2.8Привязка имен
- •10.3Члены класса
- •10.3.1Тип экземпляра
- •10.3.2Члены сформированных типов
- •10.3.3Наследование
- •10.3.4Модификатор new
- •10.3.5Модификаторы доступа
- •10.3.6Составные типы
- •10.3.7Статические члены и члены экземпляра
- •10.3.8Вложенные типы
- •10.3.8.1Полные имена
- •10.3.8.2Объявленная доступность
- •10.3.8.3Скрытие
- •10.3.8.4Доступ this
- •10.3.8.5Доступ к частным и защищенным членам типа-контейнера
- •10.3.8.6Вложенные типы в универсальных классах
- •10.3.9Зарезервированные имена членов
- •10.3.9.1Имена членов, зарезервированные для свойств
- •10.5Поля
- •10.5.1Статические поля и поля экземпляров
- •10.5.2Поля только для чтения
- •10.5.2.1Использование статических полей только для чтения вместо констант
- •10.5.2.2Отслеживание версий констант и статических полей только для чтения
- •10.5.3Поля с модификатором volatile
- •10.5.4Инициализация поля
- •10.5.5Инициализаторы переменных
- •10.5.5.1Инициализация статического поля
- •10.5.5.2Инициализация поля экземпляра
- •10.6Методы
- •10.6.1Параметры метода
- •10.6.1.1Параметры по значению
- •10.6.1.2Параметры по ссылке
- •10.6.1.3Выходные параметры
- •10.6.1.4Массивы параметров
- •10.6.2Статические методы и методы экземпляра
- •10.6.3Виртуальные методы
- •10.6.4Переопределяющие методы
- •10.6.5Запечатанные методы
- •10.6.6Абстрактные методы
- •10.6.7Внешние методы
- •10.6.8Разделяемые методы
- •10.6.9Методы расширения
- •10.6.10Тело метода
- •10.6.11Перегрузка метода
- •10.7Свойства
- •10.7.1Статические свойства и свойства экземпляра
- •10.7.2Методы доступа
- •10.7.3Автоматически реализуемые свойства
- •10.7.4Доступность
- •10.7.5Виртуальные, запечатанные, переопределяющие и абстрактные методы доступа
- •10.8События
- •10.8.1События, подобные полям
- •10.8.2Методы доступа к событиям
- •10.8.3Статические события и события экземпляров
- •10.8.4Виртуальные, запечатанные, переопределяющие и абстрактные методы доступа
- •10.9Индексаторы
- •10.9.1Перегрузка индексатора
- •10.10Операторы
- •10.10.1Унарные операторы
- •10.10.2Бинарные операторы
- •10.10.3Операторы преобразования
- •10.11Конструкторы экземпляров
- •10.11.1Инициализаторы конструкторов
- •10.11.2Инициализаторы переменных экземпляров
- •10.11.3Выполнение конструктора
- •10.11.4Конструкторы по умолчанию
- •10.11.5Закрытые конструкторы
- •10.11.6Необязательные параметры конструктора экземпляров
- •10.12Статические конструкторы
- •10.13Деструкторы
- •10.14Итераторы
- •10.14.1Интерфейсы перечислителя
- •10.14.2Перечислимые интерфейсы
- •10.14.4Объекты перечислителя
- •10.14.4.1Метод MoveNext
- •10.14.4.2Свойство Current
- •10.14.4.3Метод Dispose
- •10.14.5Перечислимые объекты
- •10.14.5.1Метод GetEnumerator
- •10.14.6Пример реализации
- •11.Структуры
- •11.1Объявления структур
- •11.1.1Модификаторы структуры
- •11.3Различия между классом и структурой
- •11.3.1Семантика значений
- •11.3.2Наследование
- •11.3.3Присваивание
- •11.3.4Значения по умолчанию
- •11.3.5Упаковка и распаковка
- •11.3.6Действие ключевого слова this
- •11.3.7Инициализаторы полей
- •11.3.8Конструкторы
- •11.3.9Деструкторы
- •11.3.10Статические конструкторы
- •11.4Примеры структур
- •11.4.1Тип целочисленного значения в базе данных
- •11.4.2Логический тип базы данных
- •12.Массивы
- •12.1Типы массива
- •12.1.2Массивы и универсальный интерфейс iList
- •12.2Создание массива
- •12.3Доступ к элементам массива
- •12.4Члены массива
- •12.5Ковариация массивов
- •12.6Инициализаторы массива
- •13.Интерфейсы
- •13.1Объявления интерфейсов
- •13.1.1Модификаторы интерфейса
- •13.1.2Модификатор partial
- •13.1.3Списки параметров типа варианта
- •13.1.3.1Безопасность вариативности
- •13.1.3.2Вариантные преобразования
- •13.1.4Базовые интерфейсы
- •13.1.5Тело интерфейса
- •13.2Члены интерфейса
- •13.2.1Методы интерфейса
- •13.2.2Свойства интерфейса
- •13.2.3События интерфейса
- •13.2.4Индексаторы интерфейса
- •13.2.5Доступ к членам интерфейса
- •13.3Полные имена членов интерфейса
- •13.4Реализация интерфейсов
- •13.4.1Явные реализации членов интерфейса
- •13.4.2Уникальность реализованных интерфейсов
- •13.4.3Реализация универсальных методов
- •13.4.4Сопоставление интерфейсов
- •13.4.5Наследование реализаций интерфейсов
- •13.4.6Повторная реализация интерфейса
- •13.4.7Абстрактные классы и интерфейсы
- •14.Перечисляемые типы
- •14.1Объявления перечислений
- •14.2Модификаторы перечисления
- •14.3Члены перечисления
- •14.5Значения перечисления и операции
- •15.Делегаты
- •15.1Объявления делегатов
- •15.2Совместимость делегатов
- •15.3Создание экземпляра делегата
- •15.4Вызов делегата
- •16.Исключения
- •16.1Причины исключений
- •16.2Класс System.Exception
- •16.3Обработка исключений
- •16.4Общие классы исключений
- •17.Атрибуты
- •17.1Классы атрибутов
- •17.1.1Использование атрибутов
- •17.1.2Позиционные и именованные параметры
- •17.1.3Типы параметров атрибута
- •17.2Спецификация атрибута
- •17.3Экземпляры атрибутов
- •17.3.1Компиляция атрибута
- •17.3.2Извлечение экземпляра атрибута во время выполнения
- •17.4Зарезервированные атрибуты
- •17.4.1Атрибут AttributeUsage
- •17.4.2Атрибут Conditional
- •17.4.2.1Условные методы
- •17.4.2.2Классы условных атрибутов
- •17.4.3Атрибут Obsolete
- •17.5Атрибуты для взаимодействия
- •17.5.1Взаимодействие с компонентами com и Win32
- •17.5.2Взаимодействие с другими языками .Net
- •17.5.2.1Атрибут IndexerName
- •18.Небезопасный код
- •18.1Небезопасные контексты
- •18.2Типы указателя
- •18.3Фиксированные и перемещаемые переменные
- •18.4Преобразования указателей
- •18.4.1 Массивы указателей
- •18.5Указатели в выражениях
- •18.5.1Косвенное обращение по указателю
- •18.5.2Доступ к члену по указателю
- •18.5.3Доступ к элементу по указателю
- •18.5.4Оператор адреса
- •18.5.5Увеличение и уменьшение указателя
- •18.5.6Арифметические операции с указателем
- •18.5.7Сравнение указателей
- •18.5.8Оператор sizeof
- •18.6Оператор fixed
- •18.7Буферы фиксированного размера
- •18.7.1Объявления буферов фиксированного размера
- •18.7.2Буферы фиксированного размера в выражениях
- •18.7.3Проверка определенного присваивания
- •18.8Выделение стека
- •18.9Динамическое выделение памяти
- •Комментарии к документации
- •Введение
- •Рекомендованные теги
- •Обработка файла документации
- •Формат строки идентификатора
- •Примеры строк идентификаторов
- •Исходный код c#
- •Результирующий xml
- •Ключевые слова
- •Литералы
- •Операторы и знаки пунктуации
- •Директивы предварительной обработки
- •Синтаксис
- •Основные принципы
- •Переменные
- •Выражения
- •Операторы
- •Пространства имен
- •Структуры
- •Массивы
- •Интерфейсы
- •Перечисления
- •Делегаты
- •Атрибуты
- •Грамматические расширения для небезопасного кода
- •© Корпорация Майкрософт (Microsoft Corp.), 1999-20101998. Все права защищены. Присылайте нам свои исправления, комментарии, отзывы и предложения по адресу csharp@microsoft.Com
13.2.4Индексаторы интерфейса
Индексаторы интерфейса объявляются с использованием объявлений_индексаторов_интерфейса:
объявление_индексатора_интерфейса: атрибутынеобязательно newнеобязательно тип this [ список_формальных_параметров ] { методы_доступа_к_интерфейсу }
В объявлении индексатора интерфейса атрибуты, тип и список_формальных_параметров имеют такой же смысл, что и в объявлении индексатора класса (§10.9).
Методы доступа в объявлении индексатора интерфейса соответствуют методам доступа в объявлении индексатора класса (§10.9) за тем исключением, что тело метода доступа должно всегда быть точкой с запятой. Таким образом, методы доступа просто указывают, каким является индекс: доступным на чтение и запись, только на чтение или только на запись.
Все типы формальных параметров индексатора интерфейса должны быть безопасны при вводе. Кроме того, любой из типов формальных параметров out или ref также должен быть безопасным при выводе. Обратите внимание, что даже параметры out должны быть безопасными при вводе, согласно ограничению базовой платформы выполнения.
Тип индексатора интерфейса должен быть безопасным при выводе, если существует метод доступа get, а также безопасным при вводе, если существует метод доступа set.
13.2.5Доступ к членам интерфейса
Доступ к членам интерфейса осуществляется с использованием выражений доступа к членам (§7.6.4) и доступа к индексаторам (§7.6.6.2) в форме I.M и I[A], где I указывает тип интерфейса, M — метод, свойство или событие этого типа интерфейса, а A — список аргументов индексатора.
Для интерфейсов, которые наследуют строго от одного предка (каждый интерфейс в цепочке наследования имеет только один прямой базовый интерфейс или не имеет его вовсе), результаты применения правил поиска членов (§7.4), вызова методов (§7.6.5.1) и доступа к индексатору (§7.6.6.2) аналогичны результатам для классов и структур: производные члены скрывают соответствующие базовые члены с тем же именем или той же подписью. Однако в интерфейсах с множественным наследованием могут происходить неоднозначности, связанные с объявлением в двух (или более) базовых интерфейсах методов с одинаковыми именами или подписями. В данном разделе приводится несколько примеров подобных ситуаций. Во всех случаях для разрешения таких неоднозначностей можно использовать явное приведение типов.
В этом примере
interface IList { int Count { get; set; } }
interface ICounter { void Count(int i); }
interface IListCounter: IList, ICounter {}
class C { void Test(IListCounter x) { x.Count(1); // Error x.Count = 1; // Error ((IList)x).Count = 1; // Ok, invokes IList.Count.set ((ICounter)x).Count(1); // Ok, invokes ICounter.Count } }
выполнение первых двух операторов ведет к ошибкам при компилировании, поскольку поиск членов (§7.4) метода Count в интерфейсе IListCounter является неоднозначным. Как показано в этом примере, неоднозначность разрешается путем приведения переменной x к типу соответствующего базового интерфейса. Такое приведение не требует дополнительных затрат ресурсов во время выполнения — оно просто означает, что при компилировании экземпляр будет рассматриваться как находящийся на предыдущем уровне наследования.
В этом примере
interface IInteger { void Add(int i); }
interface IDouble { void Add(double d); }
interface INumber: IInteger, IDouble {}
class C { void Test(INumber n) { n.Add(1); // Invokes IInteger.Add n.Add(1.0); // Only IDouble.Add is applicable ((IInteger)n).Add(1); // Only IInteger.Add is a candidate ((IDouble)n).Add(1); // Only IDouble.Add is a candidate } }
при вызове метода n.Add(1) выбирается метод IInteger.Add в результате применения правил разрешения перегрузки, рассматриваемых в §7.5.3. Точно так же при вызове метода n.Add(1.0) выбирается метод IDouble.Add. Если вставлено явное приведение типов, кандидатом является только один метод, что позволяет избежать неоднозначности.
В этом примере
interface IBase { void F(int i); }
interface ILeft: IBase { new void F(int i); }
interface IRight: IBase { void G(); }
interface IDerived: ILeft, IRight {}
class A { void Test(IDerived d) { d.F(1); // Invokes ILeft.F ((IBase)d).F(1); // Invokes IBase.F ((ILeft)d).F(1); // Invokes ILeft.F ((IRight)d).F(1); // Invokes IBase.F } }
член IBase.F скрыт членом ILeft.F. В результате при вызове метода d.F(1) выбирается метод ILeft.F несмотря на то, что метод IBase.F не скрыт явным образом в пути доступа, идущем через интерфейс IRight.
Интуитивное правило скрытия членов в интерфейсах с множественным наследованием звучит так: если член скрыт в одном из путей доступа, он скрыт и во всех остальных путях доступа. Поскольку в пути доступа от IDerived через ILeft к IBase метод IBase.F скрыт, этот член также является скрытым в пути доступа от IDerived через IRight до IBase.
