среда, 25 ноября 2009 г.

C#4.0 Optional Arguments

В новом C# 4.0 появилась возможность задавать значения по умолчанию для параметров функции. Данное нововведение, очевидно, перекочевало с С++ и поможет сделать код более компактным (ранее приходилось создавать тучу перегруженных функций, что было весьма неудобно).
1
Как видно из рисунка выше объявление функции с параметрами по умолчанию ничуть не отличается от того, которое есть в С++, однако C# предлагает большую гибкость. К примеру параметры по умолчанию можно передавать в разном порядке:
2
Передача параметра имеет вид
“Имя переменной”:”Значение”
Думаю данное нововведение будет весьма полезным для разработчиков.

вторник, 24 ноября 2009 г.

C# Delegate Stub

При работе с делегатами в C# есть одно маленькое неудобство: нужно выполнять проверку на null, иначе мы получим исключение.

1

Недавно нашел в сети весьма элегантное решение данной проблемы:

2

Для того, что бы не делать проверок, достаточно написать небольшую заглушку delegate {}; при объявлении. Теперь никакие исключения не возникают)

Ссылки: http://habrahabr.ru/blogs/net/67991/

суббота, 14 ноября 2009 г.

C++0x Повторное использование лямбда-выражений

Продолжу обзор лямбда-выражений. Еще одно важное их достоинство - это возможность повторного использования и передача как параметр функции. Для сохранения лямбда-выражений в переменную используется класс std::tr1::function.




C++0x Lambda Expressions

Одним из значительных нововведений в новом С++ являются лямбда выражения. Они перекочевали к нам от функциональных языков, сначала в С# 3.0, а теперь и в новый C++0x.
Лямбда выражения представляют собой небольшие программные конструкции, которые можно вставить прямо внутри какого либо выражения. Возможность оценить лямбда выражения дает нам новая Visual Studio 2010 и GCC.  Изначально их синтаксис может показаться довольно неудобным, но если к нему привыкнуть, они помогут вам сберечь много времени, а код сделать более лаконичным.

Приведем небольшой пример. Допустим есть вектор целых чисел и нам нужно посчитать, сколько чисел больше 5. С помощью лямбда выражений это делается весьма компактно.



Рассмотрим синтаксис лямбда выражения более подробно:


1) Список захвата или capture list
2) Список параметров
3) Изменение параметра, переданного по значению (может быть опущено)
4) Спецификация исключения (может быть опущено)
5) Возвращаемый тип
6) Тело лямбда выражения



Начнем с конца. Каждое выражение имеет тело, которое заключается в фигурные скобки и возвращаемый тип. Тут требования выступают такие же, как и к обычной функции языка С или любому другому блоку кода. Возвращаемый тип можно не указывать, в таком случае компилятор попробует определить его самостоятельно.

Для лямбда выражения можно определить список исключений, которые она может генерировать.

В круглых скобках мы указываем список параметров. Параметры могут передаваться как по значению, так и по ссылке, они могут быть константными и т.п., все как при объявлении функций. Но накладываются также и некоторые ограничения - параметры не могут иметь значений по умолчанию.

Теперь подошли к самому интересному. Любое лямбда-выражение начинается с квадратных скобок - список захвата или capture list. Значит это следующее - выражения могут обращаться к внешним переменным, которые находятся в области видимости (как по значению так и по ссылке). Список между [] определяет к каким и как именно мы будем обращаться к внешним переменным. Таким образом предыдущий пример мы можем переписать в несколько измененном виде:



 Возможны следующие варианты:
 [] - Нет обращения к внешним переменным.
 [=] - Обращение ко всем внешним переменным по значению.
 [&] - Обращение ко всем внешним переменным по ссылке.
 [=, &x] - Обращение ко всем по значению, кроме переменной x
 [&, x] - Обращение ко всем по ссылке, кроме х.
 [x, &y, z] - Обращение только к переменным x, y, z (к y по ссылке). Доступ к другим переменным отсутствует.

Как видим списки захвата дают нам большую гибкость при работе с лямбда выражениями.

При обращении к внешним переменным нужно учесть несколько нюансов.
Допустим есть следующее лямбда выражение, в котором мы локально изменяем внешнюю переменную (обращаюсь по значению) и выводим ее на экран:




К сожалению такой код компилируется с ошибкой:
Error 1 error C3491: 'X': a by-value capture cannot be modified in a non-mutable lambda main.cpp 8 1 LambdaExpressions

Попробуем разобраться почему возникает такая ошибка. Сами по себе лямбда выражения представляют собой анонимные функторы, которые генерируется компилятором. Для выражения выше генерируется нечто следующее:

Вся проблема в том, что оператор генерируется с модификатором const, впоследствии чего переменная Х не может быть модифицирована. Решением проблемы является добавление ключевого слова mutable.


Второй нюанс при обращении к членам класса. Приведу сразу пример:

Компиляция этого кода также приведет к ошибке:
Error 1 error C3480: 'Object::X': a lambda capture variable must be from an enclosing function scope \main.cpp 11 1 LambdaExpressions

Компилятор говорит, что захватываемая переменная должна быть в области видимости. Для обращения к членам класса нужно вместо [X] объявить [this]. Код компилируется без проблем, но при этом обращение к членам класса осуществляется только по ссылке. Любые попытки сделать обращение по значению приведут к ошибке.

Как видим лямбда выражения являются мощным инструментов будущего С++0х, который позволяет значительно упростить работу и сделать код более компактным.

понедельник, 9 ноября 2009 г.

Visual Studio 2010 Toolbox search

Еще одна классная фича новой IDE - возможность быстрого поиска и выбора элемента в Toolbox. Для ее использования нужно установить фокус на окне Toolbox (кликнуть мышью либо комбинацией Ctrl + Alt + X) и начать вводить текст. При этом в строке состояния вы увидите соответствующую информация о вводе:



По мере ввода, VS будет автоматически  подсвечивать (и выбирать) подходящий элемент. Для перехода к следующему элементу используется клавиша Tab, для отмены поиска - Esc.

Небольшая, но приятная функция).

воскресенье, 8 ноября 2009 г.

Data Parallelism (Task Parallel Library) в NET4.

Я уже писал ранее о некоторых нововведениях NET4 и о том, как можно легко распараллелить запросы с помощью  Parallel LINQ. В .NET4 это не единственное нововведение для задач параллельного программирования, нам предоставляется возможность с такой же легкостью распараллелить циклы for и foreach. Для этого служит новое пространство имен System.Threading.Tasks.Parallel .

Рассмотрим, в качестве примера, код умножения матрицы:


Данный код легко превращается в параллельную программу:



В целях эксперимента я решил замерить скорость выполнения умножения матрицы 1000х1000 на 1 и 2 ядрах. Результаты получились следующие:
1 поток  - 40.657
2 потока -  23.514

Как и ожидалось, прирост почти в два раза.


Ссылки и другие примеры: http://msdn.microsoft.com/en-us/library/dd537608(VS.100).aspx




Visual Studio 2010 Code Metrics

Еще одно интересное нововведение Visual Studio 2010 - это возможность оценивать сложность и переносимость кода. Данная функция будет полезной для команд разработчиков, поскольку можно увидеть текущее состояние проекта и определить потенциально проблемные участки кода.

Запустить подсчет статистики можно несколькими способами:
  • Solution Explorer - Правой кнопкой по проекту - Calculate Code Metrics
  • Меню Analyze - Calculate Code Metrics for ...
  • Меня View - Other windows - Code Metrics Results. 
Предоставляются следующие данные:
  • Maintainability Index - "ремонтопригодность" =) кода. Подсчитывается индекс от 0 до 100,  который определяет сложность сопровождения кода. Данный параметр вычисляется на основании других - Cyclomatic Complexity и Lines of Code. Чем выше число, тем лучше. В той же колонке можно увидеть цветной индикатор, который имеет след. значения: зеленый - от 20 до 100, желтый - от 10 до 19, и красный - от 0 до 9. 
  • Cyclomatic Complexity -  структурная сложность кода. Тут просто подсчитывается количество операторов if, switch, do, while, foreach, for loops в блоке кода. Чем меньше, тем лучше.
  • Depth of Inheritance -  подсчитывает глубину иерархии наследования.
  • Class Coupling -  определяет количество связей (через локальные переменные, возвращаемые значения, вызовы методов и т. п.). При подсчете пропускаются встроенные типы. Разумеется, чем меньше связей, тем лучше переносимость кода.
  • Lines of Code - количество строк кода. При подсчете пропускаются комментарии, скобки, пробелы и т.п. 


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



Также Visual Studio 2010 позволяет отображать только определенные колонки и  сделать экспорт результатов в Excel.

Code Metrics работает только в управляемом коде, а жаль :'(

Ссылки: http://msdn.microsoft.com/en-us/library/bb385910.aspx

суббота, 7 ноября 2009 г.

Linq-To-Entity Dynamic Search

Недавно столкнулся с задачей динамического поиска по таблице используя Linq-To-Entity. Поиск нужно выполнять по любому полю, опционально должны быть настройки: "Содержит", "Начинается", "Заканчивается", "Равно".  А также критериев поиска может быть любое количество.

К сожалению стандартные средства LINQ не предоставляют подобной гибкости. Одним из решений было использовать LINQ Dynamic Query API. Данная библиотека совместима с любым LINQ провайдером данных (LINQ to SQL, LINQ to Objects, LINQ to XML, LINQ to Entities, LINQ to SharePoint, LINQ to TerraServer). Вместо использования операторов языка и лямбда выражений, она предоставляет строковые расширения. Например.

Подобная система сводится к простой генерации строки запроса, что не составляет особого труда.
Ссылки для скачивания http://msdn.microsoft.com/en-us/vcsharp/bb894665.aspx

http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx
http://www.codeproject.com/KB/WPF/LtoE.aspx

вторник, 3 ноября 2009 г.

C# Operator ??

В C# есть замечательный оператор -??. С помощью него следующее выражение:
t = (text == null) ? "" : text;
можно записать в более изящном виде:
t = text ?? "";

понедельник, 2 ноября 2009 г.

Visual Studio F1 Help Shortcut


Наиболее раздражающая вещь в Visual Studio для меня - это случайно нажать вместо Escape клавишу F1. При этом появляется окно "Help Update In Progress", которое блокирует основное окно на несколько минут.


Погуглив несколько минут, я нашел решение - это отключить клавишу F1 как таковую.

Жить стало легче (: