C Sharp 3.0 - C Sharp 3.0
Язык программирования C # версия 3.0 была выпущена 19 ноября 2007 г. как часть .NET Framework 3.5. Он включает новые функции, вдохновленные функциональное программирование языки, такие как Haskell и ML, и во многом обусловлен внедрением Интегрированный языковой запрос (LINQ) в Common Language Runtime.[1] В настоящее время он не стандартизирован ни одним организация стандартов.
Возможности C # 3.0
LINQ (интегрированный в язык запрос)
LINQ - это новый расширяемый универсальный язык запросов Microsoft для многих видов источников данных, включая коллекции простых объектов, XML-документы, базы данных и т. д., который тесно интегрирован с другими средствами языка C #. Синтаксис отличается от, но заимствует из SQL. Пример:
int[] множество = { 1, 5, 2, 10, 7 };// Выбираем квадраты всех нечетных чисел в массиве, отсортированные в порядке убыванияIEnumerable<int> запрос = из Икс в множество куда Икс % 2 == 1 Сортировать по Икс нисходящий Выбрать Икс * Икс;// Результат: 49, 25, 1
Для реализации LINQ во многие коллекции был добавлен широкий спектр новых методов через System.Linq.Enumerable
учебный класс. Выражения LINQ транслируются для использования этих функций перед компиляцией. В качестве альтернативы, которая иногда бывает более мощной или прямой, к этим функциям можно обращаться напрямую.[2] При этом больше используются лямбда-функции, которые обсуждаются ниже. Следующее функционально идентично приведенному выше примеру.
IEnumerable<int> запрос = множество.Где(Икс => Икс % 2 == 1).OrderByDescending(Икс => Икс).Выбирать(Икс => Икс * Икс);// Результат: 49, 25, 1 с использованием массива, как определено в предыдущем примере
Инициализаторы объектов
Покупатель c = новый Покупатель(); c.Имя = "Джон";
можно написать
Покупатель c = новый Покупатель { Имя = "Джон" };
Инициализаторы коллекций
Мой список список = новый Мой список();список.Добавлять(1);список.Добавлять(2);
можно записать как
Мой список список = новый Мой список { 1, 2 };
при условии, что Мой список
орудия System.Collections.IEnumerable
и имеет общественный Добавлять
метод.[3]
Вывод типа локальной переменной
Локальная переменная вывод типа:
вар Икс = новый Словарь<нить, Список<плавать>>();
взаимозаменяем с
Словарь<нить, Список<плавать>> Икс = новый Словарь<нить, Список<плавать>>();
Эта функция не просто удобная синтаксический сахар для более коротких объявлений локальных переменных, но это также необходимо для объявления переменных анонимных типов. Однако контекстное ключевое слово «var» может появляться только в объявлении локальной переменной.
Анонимные типы
Анонимные типы предоставляют удобный способ инкапсулировать набор свойств, доступных только для чтения, в один объект без необходимости сначала явно определять тип. Имя типа создается компилятором и недоступно на уровне исходного кода. Тип свойств определяется компилятором.
вар Икс = новый { Имя = "Джон", Фамилия = "Лань" };
Анонимные типы - это ссылочные типы, производные непосредственно от объекта. Компилятор дает им имя, хотя ваше приложение не может получить к нему доступ. С точки зрения среды CLR анонимный тип ничем не отличается от любого другого ссылочного типа, за исключением того, что он не может быть приведен к любому типу, кроме объекта.
Если два или несколько анонимных типов имеют одинаковое количество и тип свойств в одном порядке, компилятор рассматривает их как один и тот же тип, и они используют одну и ту же информацию о типе, созданную компилятором.[4]
Лямбда-выражения
Лямбда выражения обеспечивают краткий способ записи значений анонимных функций первого класса. Сравните следующий фрагмент кода C # 2.0:
listOfFoo.Где(делегировать(Фу Икс) { возвращаться Икс.Размер > 10; });
с этим эквивалентом C # 3.0:
listOfFoo.Где(Икс => Икс.Размер > 10);
В приведенных выше примерах лямбда-выражения - это просто сокращенный синтаксис для анонимных делегатов с выводом типа для параметров и возвращаемого типа. Однако в зависимости от контекста, в котором они используются, компилятор C # также может преобразовывать лямбда-выражения в ASTs которые затем могут быть обработаны во время выполнения. В приведенном выше примере, если listOfFoo
это не просто коллекция в памяти, а оболочка вокруг таблицы базы данных, он может использовать этот метод для преобразования тела лямбда-выражения в эквивалентное выражение SQL для оптимизированного выполнения. В любом случае само лямбда-выражение выглядит в коде точно так же, поэтому способ его использования во время выполнения прозрачен для клиента.
Деревья выражений
Выражения, такие как х <= у
, а = Ь + с
, или даже лямбда-функции и другие сложные формы могут быть созданы динамически с помощью деревья выражения. Большая часть функциональности обеспечивается статическими методами класса System.Linq.Expressions.Expression
. В этом пространстве имен также есть различные новые классы, которые представляют выражения и частичные выражения, созданные этими методами, как программные объекты. К ним относятся Двоичное выражение
, который может представлять х <= у
; LambdaExpression
и много других. В сочетании с аспектами отражение API, это может быть очень мощный инструмент, хотя его немного сложно писать и отлаживать.[5][6]
Автоматические свойства
Компилятор генерирует частную переменную экземпляра и соответствующий код доступа и мутатора, например:
общественный нить Имя { получать; частный набор; }
Методы расширения
Разработчики могут использовать методы расширения для добавления новых методов к общедоступному контракту существующего типа CLR без необходимости его подкласса или перекомпиляции исходного типа. На самом деле методы расширения - это своего рода синтаксический сахар, который создает иллюзию добавления новых методов к существующему классу вне его определения. Иллюзия достигается с помощью определения статического метода, который вызывается, как если бы это был метод экземпляра, где получатель вызова (то есть экземпляр) привязан к первому параметру метода, украшенному ключевым словом это
.
Требования к методу расширения следующие:
- Метод расширения должен быть определен в статическом классе.
- Метод расширения должен быть определен как статический метод.
- Первый параметр метода расширения должен иметь следующую форму, где тип - это имя расширяемого типа:
это тип имя_параметра
- Метод расширения может дополнительно определять другие параметры, чтобы следовать
это
параметр.
Этот пример класса демонстрирует определение и использование Оставили
метод расширения для строк:
общественный статический учебный класс StringExtensions{ общественный статический нить Оставили(это нить s, int п) { возвращаться s.Подстрока(0, п); }} нить s = "фу бар";s.Оставили(3); // то же, что StringExtensions.Left (s, 3), который возвращает «foo»;
Частичные методы
Частичные методы позволяют генераторам кода создавать объявления методов в качестве точек расширения, которые включаются в компиляцию только в том случае, если кто-то фактически реализует их в другой части частичного класса.[7]
Рекомендации
- ^ Андерсон, Тим (14 ноября 2006 г.). «C # опережает Java - ведущий архитектор рисует радужную картину C #». Reg Разработчик. Реестр. Получено 2007-01-20.
- ^ Вальтер, Стивен (2008). Освобожденный ASP.NET 3.5. Индиана, США: SAMS. стр.916–917. ISBN 978-0-672-33011-7.
Я обнаружил, что использую синтаксис метода больше, чем синтаксис запроса, потому что синтаксис запроса является подмножеством синтаксиса метода.
- ^ Торгерсен, Мэдс (10 октября 2006 г.). "Что такое коллекция?". Мягкие размышления доктора Т.. Получено 2009-06-18.
- ^ «Анонимные типы». Руководство по программированию на C #. Microsoft. Июль 2008 г.. Получено 2009-06-18.
- ^ Вальтер, Стивен (2008). Освобожденный ASP.NET 3.5. Индиана, США: SAMS. стр.950–952. ISBN 978-0-672-33011-7.
- ^ "Деревья выражений". Руководство разработчика .NET Framework. Microsoft. Получено 2009-04-26.
- ^ «Частные классы и методы». Руководство по программированию на C #. Microsoft. Получено 2009-04-28.