Новые возможности .NET 4.0: C# 4.0 (исходники)Источник: gotdotnet outcoldman
После выхода Visual Studio 2010 - первым делом нужно разобраться, что же дает нового нам C# 4.0 (на время написания статьи была версия beta 1). Первым делом должен вам порекомендовать примеры C# 4.0, которые можно скачать отсюда (там же есть документ New Features in C# 4.0, которая послужила основой для этой стаьи). Документацию по .Net Framework 4.0 можно также посмотреть в MSDN. Итак, давайте посмотрим, что же нам дает C# версии 4.0.
Чтобы понять, что такое Dynamic Language Runtime (далее просто DLR), я должен изначально обратить ваш взор на следующую схему, иллюстрирующую архитектуру DLR: Именно! Теперь в .net можно еще и скриптовые языки использовать, такие как IronRuby и IronPython. Конечно, вряд ли многие будут ими пользоваться, но это дает дополнительные возможности в реализации ваших приложений. Для того, чтобы иметь возможность использовать данные языки необходимо скачать и установить соответствующие проекты: Так же, предоставляется исходники DLR, при помощи которых вы, наверняка, сможете создать свой динамический язык для .NET, если у вас есть в этом необходимость. Теперь давайте рассмотрим подробнее, что из себя представляет DLR. Итак DLR включает в себя Expression Trees (деревье выражения - если переводить дословно), которые просто являются представлением вызовов методов или бинарных операций в виде дерева, их функциональность можно посмотреть на следующем примере В этом примере мы сначала описываем лямбда выражение num=>num<5, а затем при помощи объектов от Expression Trees разбираем данное выражение. Call Site caching в DLR - это и есть динамическое представление вызовов методов динамических объектов или операций над динамическим объектами. DLR кеширует характеристики объектов (о типах объектах), а так же об операции, и если данная операция уже была выполнена ранее, тогда всю необходимую информацию DLR получит уже из кеша. И последнее в DLR - это набор классов и интерфейсов: IDynamicMetaObjectProvider, DynamicMetaObject, DynamicObject и ExpandoObject. Давайте опять посмотрим на примере, как нам это может пригодиться, и зачем нам вообще нужен этот DLR: blockquote { background-color:white; border-left: 2px solid gray; margin-left:5px; padding: 5px 10px 5px 10px; } На удивление данный код скомпилируется и запустится. Все дело в волшебном слове dynamic, оно нам позволяет вызывать любые по имени свойства или методы, а так же приводить объект к любому типу. Во время Runtime (выполнения кода) вылетят ошибки, Error 1: о том, что метод не найден, Error 2: о том, что double невозможно привести к int. Попробуем их исправить: для исправления первой ошибки наш класс Test1 отнаследуем от типа System.Dynamic.DynamicObject и перегрузим один из методов, для исправления второй просто явно укажем преобразование типов: Теперь наш код будет работать. Переменная str получить значение "Test1 is dynamic object!", а i значение 7. Конечно, необязательно наследоваться от класса DynamicObject, можно отнаследоваться и от интерфейса IDynamicMetaObjectProvider, но тогда нужно будет самому реализовывать метод DynamicMetaObject GetMetaObject(Expression parameter), и более того реализовывать свой тип, унаследованный от DynamicMetaObject, ну в любом случае варианты есть - так что можно взять на вооружение. Функциональность необязательных параметром существует во многих языках, в C# она же приходит только в версии 4.0, и более того здесь же появляются еще и именованные параметры. Теперь есть возможность устанавливать дефолтные значения у параметров методов, а так же возможность установки значения параметра по имени при вызове метода. Давайте рассмотрим на примере: class Test1 Теперь из-за переименование параметра метода, код может и не скомпилироваться, если кто-то использовал установку значения по имени, так что нужно быть аккуратнее. В дополнение хочу сказать, что если все таки будет у класса Test1 метод void Method(int a), тогда при вызове o.Method(1) вызовится именно он, а не метод из примера с дефолтными значениями. 3. Возможности для COM InteropDLR так же дал новые возможности для COM Interop, теперь можно COM объекты определять как динамические (точнее они уже являются в большинстве своем динамического типа) и не приводить постоянно получаемые объекты к определенным типам для вызова методов или свойств. excel.Cells[1, 1].Value = "Hello"; Данный пример взят из документа New Futures in C# 4.0 С одной стороны приятно, что теперь не нужно мучаться и находить к какому же типу нужно привести объект, чтобы вызвать его свойство или метод, но с другой стороны теряется IntelliSense. 4. Новое в genericВ C# 4.0 обогатился и generic новой функциональностью. Можно теперь у интерфейсов и у делегатов перед определением generic типов писать out и in, зачем это чуть дальше, а сначала рассмотрим пример.При работе с generic часто хочется сделать что то типа такого: IList<string> strings = new List<string>();Но нельзя. Потому, что следом можно написать: objects[0] = 5;То есть, изначально у нас был список строк, потом обозначили его как список объектов, и хотим уже работать с ним, как с объектами, установливая любой другой объект в него, хотя список до сих пор является списком строк. Но, если вдуматься, то можно представит, что если бы список был только для чтения, то мы бы уже не смогли ничего нарушить, и там бы логика была ясна, потому следующий код на C# 4.0 будет работать: IEnumerable<object> objects = strings;
Огромную полезность данная функциональность принесет в работе с linq, там часто возникают проблемы, что возвращаем объекты одного типа, а нужно получить список другого типа (базового).Итак, как же такое стало возможным. Сначала рассмотрим слово out. Теперь интерфейс IEnumerable<T> объявлен как IEnumerable<out T>, где out обозначает, что тип T может быть использован только для возвращения значений, в другом случае компилятор будет ругаться, ну и более того это дает нам, что интерфейс IEnumerable<A> так же есть и IEnumerable<B>, если у A есть возможность приведения типа к B, если на простом примере, то IEnumerable<string>, есть теперь и IEnumerable<object>. Вот пример:public interface IEnumerable<out T> : IEnumerable Есть еще слово in. Его так же можно использовать в описании generic делегатов и интерфейсов. Несет оно такую же смысл как и слово out, только в данному случае описанный тип можно использовать только в передаче параметров, вот пример: public interface IComparer<in T> То есть в данном случае, если IComparer<object> может считаться и IComparer<string>, потому как если уж он может сравнивать объекты типа object, то и string тоже может. Так же, как я уже сказал, слова out и in можно применять и к интерфейсам, так, например: public delegate TResult Func<in TArg, out TResult>(TArg arg);
ЗаключениеТакже в .NET 4.0 появилось много новвовведений, таких как Lazy Initialiation - память под объект выделяется тогда, когда это действительно становиться нужно. Появились новые типы, как например, BigInteger - теперь не нужно для лабораторных работ студентам писать свои классы для работы с большими числами, SortedSet<T> - класс представляет собой самостоятельное балансированное дерево, которое сохраняет данные в отсортированном порядке после вставки, удаления и поиска. В общем есть еще что изучать. |