Баг в Sql Server CE


В проклятом Sql Server CE есть весёленький баг - иногда когда к нему обращаешься через LINQ он выдаёт шикарный exception: "The ntext and image data types cannot be used in WHERE, HAVING, GROUP BY, ON, or IN clauses, except when these data types are used with the LIKE or IS NULL predicates.", хотя ни ntext ни image в таблице не присутствуют вообще. Обходится все это составление строкового запроса типа: entities.Where("it.ID == '" ID "'"). Вот так вот всё оригинально.
И вообще весь этот компактный sql сервер мне весьма не нравится. Тормозной, малофункциональный, лучше конечно, чем sqlite, но до Sql Server Express очень сильно недотягивает. Зато его ставить не надо.

Невидимые контролы


Экспериментальным путём обнаружил следующую вещь: для невидимых контролов лучше ставить Visibility не Hidden, а Collapsed. Это очень сильно влияет на производительность в случае, когда они меняют размеры, особенно если используются в СontrolTemplate.
А вообще, наконец-то, оценил всю мощь DataTemplate: писать такие вещи парой строчек кода - это круто. Но что-то производительность меня не очень радует, хотя основную часть я конечно оптимизировал.

Double click в WPF-е


Обнаружил, что для контролов, у которых отсутствует OnMouseDoubleClick, обработчик двойного клика можно получать следующим способом:
private void OnItemMouseDown(object sender, MouseButtonEventArgs e)
{
    if(e.ClickCount==2)
    {
        // Здесь даблклик
    }
}
Тем же способом можно получить и тройной клик и т.д.

Создал тестовый проектик на XNA для Zune


Наваял тестовый проект на XNA под Zune, с ходящим роботом (гандамчег, с турбосквида скачал)
Создал тестовый проектик на XNA для Zune
Обнаружилась редкостная гадость: проклятая Zune понимает исключительно единственный формат картинки - 32-х битный, а учитывая 16-ти метровое ограничение на память это выглядит крайне печально, ибо только анимации хождения для робота весят 2,5 метра. Походу придётся придумывать, как использовать подгрузку данных с жесткого диска. Эх, нет чтоб поддерживать мой любимый l4a4.

NearestNeighbor у BitmapScalingMode


Узнал, что в SP1 к Net Framework 3.5 у BitmapScalingMode наконец-то ввели мод NearestNeighbor, т.е. теперь изображения можно растягивать без сглаживания (с жуткими пикселями), помнится года два назад мы сильно мучились пытаясь достичь данного эффекта, но так и не достигли, а нынче просто подарок судьбы.

Внезапно


День великих открытий: я до сих пор не знал, что можно так делать:
public bool IsUsing
{
      get { return (bool)GetValue(IsUsingProperty); }
      private set { SetValue(IsUsingPropertyKey, value); }
}

Очередной баг в WPF


Наткнулся сегодня в WPF на неприятный баг - если у окна установить ResizeMode в ResizeWithGrip, то из другого потока уже не получится создать окно с ResizeMode = ResizeWithGrip. Поскольку при этом выскакивает ошибка доступа к Brush из другого потока. Как я понимаю, это связано с тем, что либо стиль окна у них там кэшируется, либо Brush, либо ещё что-то. Всегда подозревал, что для локальных ресурсов кэширование - это зло. Час убил на этот баг. (Что-то я сегодня торможу :) первый день после трёхдневного выходного сказывается. К слову как-то раз на такой фокус мы нарывались и с BitmapImage, но там это лечилось просто отключением кэширования либо Freeze.

PS. Хотел было мелкософтам отписать о баге, да лень стало это на ангельском формулировать. Ладно, глядишь кто другой отпишет.

Метки: bugswpfc#

Работа с zip-архивами


Всё таки в Microsoft были неправы, сделав интернальными столько полезных классов в .Net Framework.
Вот например, работа с *.zip файлами. Класс есть, но он интернальный, а возможность работать дана тока с пакэйджами (package - это такие zip-архивы, которые содержат Content_Types.xml, например документы 2007-го офиса). И вот зачем спрашивается надо было закрывать? Пришлось воспользоваться рефлекшеном для работы:
Assembly asm = Assembly.GetAssembly(typeof (ZipPackage));
Type ZipArchiveType = asm.GetType("MS.Internal.IO.Zip.ZipArchive");
Type ZipFileInfoType = asm.GetType("MS.Internal.IO.Zip.ZipFileInfo");
MethodInfo openOnStreamMethod = ZipArchiveType.GetMethod("OpenOnStream", BindingFlags.Static | BindingFlags.NonPublic);
object archive = openOnStreamMethod.Invoke(null, new object[] {stream, FileMode.Open, FileAccess.Read, false});
MethodInfo getFileMethod = ZipArchiveType.GetMethod("GetFile", BindingFlags.NonPublic | BindingFlags.Instance);
object contentFile = getFileMethod.Invoke(archive, new object[] {"content.xml"});
MethodInfo getStreamMethod = ZipFileInfoType.GetMethod("GetStream", BindingFlags.NonPublic | BindingFlags.Instance);
using (Stream contentStream = (Stream)getStreamMethod.Invoke(contentFile, new object[] { FileMode.Open, FileAccess.Read }))
{
// Здесь можно без проблем использовать распакованные данные
}

Метки: c#dotnetzip

MS Source Analysis


Microsoft-ы выпустили MS Source Analysis for C#, в отличии от FxCop, который анализируют уже скомпилированный код, эта утилита проверяет исходники на соответствие правилам (а правила там зверские, но их можно отключать/подключать). Также её вроде можно встроить в MSBuild и проверять на корректность кода на этапе компиляции. В общем отличная штука.
PS. В рабочем проекте в каждом файле под тысячу нарушений, впрочем, учитывая, что мы кодируем по своим правилам, а не по тем, что заложены в этой утилите, не удивительно.

Размышления на тему обучения программистов


Размышления на тему того, как надо правильно обучать программистов, навеяно комментариями к этому.
Итак, школьные годы:
1-4 классы: общее знакомство с компьютером, Windows там, MS-DOS (командную строку учить необязательно, а вот Norton Commander как минимум на уровне копирования файлов и запуска игр)
5-7 классы: знакомство с программированием, основы алгоритмизации, на примере какого-нибудь лого (кенгурёнка и прочих кукарач)
8-11 классы: алгоритмизация, лучше всего на Turbo Pascal 5, на крайний случай сойдёт и TP 7, главное никакого Delphi, иначе детей можно будет считать потерянными для мира программирования. Также можно использовать Basic (само собой под DOS), но паскаль в данном случае будет лучше
Институт:
1-ый курс: старый добрый C, основная цель курса обучить студента правильно работать с указателями и прочим стандартным вещам
2-ой курс: ООП, в основном теория, примеры на C++, но не забывая упоминать про прочие типа Smalltalk-а, Java, C# и т.д...
3-ий курс: обучение правильному построению архитектуры приложений, рефакторингу/отладке/тестированию/профайлингу и т.д. и т.п. Плюс основы функционального программирования. Факультативы по Java, C# и прочим(именно по языкам, никакого формошлепства и прочего визуального программирования). Также неплохо давать основы WinAPI, предпочтительно с какой-нибудь навороченной курсовой в конце семестра. Также как факультатив возможно введение в web-программирование, хотя это совсем не обязательно.
4-5 курсы: практика, практика, и ещё раз практика. Само собой в реальных проектах, в реальных фирмах, никакой теории уже не надо. С этого момента студенты должны учиться на своём опыте и на опыте старших коллег. Естественно это требует тесного взаимодействия ВУЗов и предприятий, чего сейчас нет и в помине.

Краткие примечания
- я считаю, что для обучения школьников наиболее подходящим языком будет Pascal (именно старый добрый процедурный паскаль, а ни в коем случае не жутчайшие Delphi или Object Pascal)
- основной недостаток паскалистов (большинства по крайне мере) - это абсолютное неумение работать с памятью, именно поэтому на первом курсе института этому должно уделяться особое внимание
- ни в коем случае нельзя использовать для обучения Deplhi(а также CBuilder, Visual C# и прочие IDE, где доминирует формошлепство), ибо как показывает практика большинство людей начавших с формошлепства так никуда и дальше и не продвигается, именно поэтому я считаю, что закупка в школы BDS`а приведёт к тому, что хороших программистов станет значительно меньше (впрочем их и так совсем немного), а вот всяких быдлокодеров, которые только и умеют, что раскидывать кнопки по форме, станет просто немерено (хотя их и так немало)
- по настоящему хороший программист без особых проблем сможет сменить язык программирования на другой(имеются ввиду естественно императивные языки, с функциональными есть своя специфика), конечно в каждом языке есть свои тонкости, но основа-то в конечном итоге у всех одна, поэтому не играет большой разницы C это, Pascal, Basic или что-то ещё.

PS. Всё это моё личное мнение, навеянное жизненным опытом, и совсем не претендующее на стопроцентную объективность.

Предыдущие записи Следующие записи