четверг, 25 октября 2007 г.

Немного о малоиспользуемых операторах С#

Вот тут можно почитать о некоторых конструкциях шарпа, которые редко используются.
В частности, для меня оказалось неожиданным то, что можно объявить generic-класс вот таким образом:


public class AbstractFactory where Products: IBuilder, new()
{
    ....
}


Обратите внимание - в данном случае new() означает, что класс Products должен иметь конструктор без параметров! Каюсь - даже и не знал, что так можно...

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

Немного о семантике

Обновился проект LinqToRdf до версии 0.3.

Кто не знает что такое Linq - вам сюда. Кто не знает что такое RDF - вам сюда.

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

P.S.: а никто не знает, где можно найти частоты встречаемости русских/английских слов (причем с учетом частей речи для английских слов, т.к. одно и то же слово там может быть, например, и наречием и существительным) в текстах различной тематики? Есть идея сделать ранжирование вариантов перевода по этой статистике... Причем сам алгоритм явно будет очень маленьким - только ему надо много-много данных :(

Update: Стоит еще обратить внимание на проект Introducing SyncLINQ. Позволяет делать data binding на LINQ-запросах.

про С++

Один товарищ написал объемистый документ с ответами на часто задаваемые вопросы про С++. Этакое собрание граблей :)
Почитать можно тут. На английском.

P.S.: а те грабли, на которые я наступил в своё время там тоже есть ;)

пятница, 12 октября 2007 г.

Обратите внимание!

Прочитал сегодня интересный пост События и многопоточный код. Стоит запомнить...

среда, 10 октября 2007 г.

Страсти-то какие!

Цитирую cnews.ru

"Ужесточение борьбы с нелегальным программным обеспечением не могло не сказаться на росте доходов производителей ПО. Так, по итогам первого полугодия 2007 г. «Лаборатория Касперского» в России, СНГ и Балтии продемонстрировала рост по сравнению с аналогичным периодом 2006 г. на 130%. Рост продаж Microsoft Russia в 2007 финансовом году вырос на рекордные 107%, продажи Autodesk в странах СНГ во II квартале финансового года составили 160%, по итогам третьего квартала 2007 финансового года продажи Adobe в России выросли на 260%."

Нет слов.

И тут я задумался: а ведь программисты (ну понятно, что "хорошие программисты" :) ) в этом отношении самые счастливые люди в стране. Нам ничего не нужно из программ.

Фактически, тот софт, что я использую может быть или безболезненно заменен на бесплатные альтернативы или же написан самостоятельно.

Зачем мне Photoshop, когда есть Paint.Net?
Зачем мне, например, WebSite Watcher, если подобная программа может быть написана на коленке за один вечер? Ну естественно, менее функциональная - так ведь там в любом случае будет всё что мне нужно - я же ее напишу-то :).
А уж если покопаться в своих экспериментальных проектах - столько всего полезного можно нарыть... :)

Да, неудобно. В том же Ворде2007 есть много интересных вещей, без которых обойтись, конечно, можно, но...

Пиратство будет жить до тех пор, пока цены на ПО не будут приведены в соответствие с его качеством и популярностью.

И если купить приличный комп сейчас себе может позволить практически любой (8-15 тыс. руб. это не такие уж большие деньги. За полгода-год их вполне реально собрать при любой зарплате), то снабдить его полностью лицензионным ПО себе позволить может только крупная фирма.

Примечание: кстати, вот в моем университете есть требование сдавать чертежи распечатанными на плоттере. Нарисованные вручную - не принимают. Скажите мне, какой студент сможет себе позволить купить AutoCad для этих целей? Те кто может - учатся совсем в других университетах...

Enum'ы с человеческим лицом!

Сегодня речь я поведу о том, как облегчить себе жизнь при работе с enum-типами. То, что использовать их нужно понимают, я думаю, все. Это удобно: код становится понятнее, вероятность совершить ошибку (если использовать вместо enum «магические» числа) – ниже и т.д. и т.п.
Все это, конечно, хорошо… Но что делать, если необходимо отображать пользователю списки (например, combobox'ы) состоящие из этих самых enum (или сводящиеся к ним)? Естественно, что пользователь не знает английского, да и в любом случае – адекватно воспринимать замену пробела символом подчеркивания он точно не будет :)
Если вспомнить про то, что юникод для дотнета – это «родное», а студия еще и корректно работает с русскими именами функций и переменных, то можно, конечно, называть значения в нашем enum русскими именами. Но! Это ж умучаешься раскладки переключать :)
Поэтому самое простое неправильное решение – это, как правило, использование строкового массива, в котором задаются отображаемые пользователю русские имена.
Можно пойти дальше и использовать вместо массива, например, Dictionary. Этот способ как минимум более надежен и шанс , что в программе появится странная ошибка если мы решим добавить еще несколько элементов в enum, резко уменьшится.
Кстати, этот способ имеет право на жизнь. Однако – он неудобен. Намного удобнее, когда описания элементов enum хранятся вместе с ними. Даже очень удобно :)
Как этого добиться? (И вот тут все должны громко воскликнуть – «Ну конечно атрибуты!»)
Первое что нам понадобится – это атрибут, через который мы будем задавать описание:

[AttributeUsage(AttributeTargets.Field)]
public class EnumDescriptionAttribute: Attribute
{
    public readonly string description;

    public EnumDescriptionAttribute(string description)
    {
        this.description = description;
    }
}

public enum etest
{
    [EnumNameAttribute("Значение 1")]
    value1,
    [EnumNameAttribute("Значение 2")]
    value2,
    …
}
Как видите – здесь все просто :)
А теперь самое сложное: получение этих описаний (чтобы отдать их пользователю).

Примечание: и вот тут-то руки и опускаются – сразу после того, как мы слышим жуткое слово reflection :) Но не пугайтесь, все не так страшно ;)

Чтобы получить наш атрибут-описание для известного значения, надо вызвать следующий код:


((EnumDescriptionAttribute)typeof(etest).GetField(p.ToString()).GetCustomAttributes(typeof(EnumDescriptionAttribute), true)[0]).description;


Примечание: стра-а-ашно??? :)

Чтобы получить имена для всех значений enum (например, чтобы сформировать список, из которого будет производиться выбор нужного значения):

public static string[] GetAllEnumDescription()
{
    T[] vals=(T[])Enum.GetValues(typeof(T));
    string[] names = new string[vals.Length];
    for (int i = 0; i < vals.Length; i++)
        names[i] = GetEnumDescription(vals[i]);
    return names;
}

public static string GetEnumDescription(T p)
{
    return ((EnumDescriptionAttribute)typeof(T).GetField(p.ToString()).GetCustomAttributes(typeof(EnumDescriptionAttribute), true)[0]).description;
}


Примечание: я решил, что данный вариант (использующий generics) функции будет полезнее – этот вариант функции можно использовать для любого enum (при условии, что у его элементов есть наш атрибут). Кому не нравится – его легко можно переделать.

Вообщем-то и всё…

P.S.: ой, нет! Чуть не забыл: если в функции GetAllEnumDescription использовать конструкцию yeld return – то она будет еще более удобна :) и один new можно будет убрать…

пятница, 5 октября 2007 г.

"Продвинутое" использование класса Settings, а также немного о Databinding

В предыдущем посте среди прочих способов сохранения настроек я упомянул класс Settings. Однако написал я про него не очень много и как-то не очень внятно. Вряд ли по тому посту будет понятно насколько это хорошая штука :) Поэтому я решил рассказать про него поподробнее и на конкретном примере. Тем более, что в сети информация все больше общего характера – просто непонятно зачем этот класс нужен. Примечание: проект я буду делать в Visual Studio 2008 Beta 2 установленной на Windows Server 2008 RC0. Принципиального отличия от VS2005 в данном случае нет. В обоих версиях студии способ работы с классом Settings одинаков.

Начнем с создания нового проекта. Будет это Windows Forms Application с одной формой (я покажу только как разработывается форма с настройками приложения):


Кидаем на форму несколько контролов, через которые и будут редактироваться наши настройки:

Собственно, ничего особенного тут нет. Я думаю справитесь :)
А теперь начинается самое интересное :) Начинаем использовать класс Settings. Для этого надо для каждого контрола проделать следующие шаги:
1. Выделить его. Переключиться на вкладку Properties и найти раздел ApplicationSettings.
2. В данном случае - для checkBox - нам нужно сохранять свойство Checked.

3 И жмем ссылку new

Здесь можно ввести название переменной, в которой будет храниться состояние нашей настройки, значение по-умолчанию (True/False) и где она будет храниться (оставляем как есть).
4. А собственно и все :)
Ну и напоследок, посмотрим как это работает. В метод button1_Click пропишем добавим следующий код:
MessageBox.Show(Properties.Settings.Default.setting1.ToString());

И мы увидим, что всё работает :)

Ну и напоследок
Что делать, если необходимо добавить какую-либо проверку значений вводимых пользователем параметров или, например, осуществлять преобразование типов?
В этом случае придется немного пописать ручками :)
Добавим свойство с методами get/set через которое и будет осуществляться доступ к настройкам:

public string Setting3
{
  get
  {
      return Properties.Settings.Default.setting3;
  }
  set
  {
      string tmp = value.ToLower();
      Properties.Settings.Default.setting3 = tmp;
  }
}

Свяжем его с соответствующим свойством у контрола на форме:

this.textBox1.DataBindings.Add("Text", this, "Setting3");

В данном случае, первый параметр - это имя свойства у контрола которое будет связываться. Второй параметр - ссылка на объект где находится свойство с которым будет производиться связывание. Ну и третий параметр - это, соответственно, имя свойсва.
И всё! Дальше всё будет работать само.
Пожалуй на этом и закончу.