Условная компиляция

вторник, 29 декабря 2009, Роман Калита

Один мой друг как-то захотел сделать демо написанного собственным потом и кровью SDK на .NET. Естественно нужно было урезать часть очень важного функционала. Сделать это нужно было так как всем известно как в .NET происходит защита исходного кода. Плохо если не сказать другим словом – обфускация.

Обфускация по сути переименование и переименование это касается только приватной или внутренней реализации программы. Но SDK в силу того что нужно выставлять часть функционала наружу поддается защите обфускатором заметно хуже.

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

Как же в такой ситуации быть? Есть необходимость собирать билд с включением или выключением определенного функционала условно.

В это случае поможет условная компиляция. Такую возможность C# как язык унаследовал от С/С++ (всем достаточно известно использование #define, #ifdef и т.п. в С/С++ ). Их хотя в шарпе уже не напишешь тех изощренных макросов как в си, но все же аналогичные директивы в C# имеют свое применение.

Пользоваться этим достаточно просто. Необходимо используя директиву #define объявить константу условной компиляции.

#define TEST

Также константу условной компиляции можно объявить используя опцию компилятора /define. А так как это можно сделать в опциях, тогда то же самое можно сделать и в свойствах проекта используя Visual Studio (вкладка Builde > Conditional compilation symbols):

image

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

При создании нового проекта для него создаются две конфигурации – Debug и Release, для первой объявлено по умолчанию две константы DEBUG и TRACE, для релизной конфигурации – только TRACE.

После объявления такую константу можно использовать либо с #if, #endif, #else директивами, либо в связке с атрибутом ConditionalAttribute. Например, код можно обернуть директивами:

#if (DEBUG)
    Debug.Listeners.Remove("Default");
    Debug.Listeners.Add(new SuperAssertTraceListener());
#endif

или с #else:

#if (DEBUG)
    stream = new StreamWriter("c:\\temp\\WorkTimeTracer.txt");
#else
    stream = null;
#endif

На директивы никаких ограничений в отличии атрибута – нет, если что-то не так код не скомпилируется. Но с атрибутом код более читабелен. На метод помеченные ConditionalAttribute накладываются следующие ограничения:

  1. Такой метод не должен возвращать значений
  2. Не должен быть объявлен в интерфейсе
  3. Не должен быть методом с идентификатором override.

Суть этих ограничений вполне логична. Ведь в конфигурациях отличных от указанной в атрибуте, тело метода будет восприниматься как комментарий. Если посмотреть на класс System.Diagnostics.Debug к примеру то там многие методы помечены этим атрибутом.

[Conditional("DEBUG")]
public static void Trace(string message)
{
    Console.WriteLine(message);
}

На самом деле применять условную компиляцию можно не только для того чтобы исключать функционал нужный для дебага, или для того чтобы сделать демку. Условную компиляцию стоит применять в “кроссплатформенной” разработке, например когда пишется клиентская часть на Silverlight и WPF, или для обычного и .NET Compact Framework

SabMakc: Следует помнить, что использовать такие директивы следует с очень большой осторожностью, т.к. могут возникнуть труднонаходимые ошибки (особенно если проект развивается длительное время).

Progg it


Этот блог зеркалируется. Оригинал взят с regfordev.blogspot.com

Компании из статьи


Microsoft Украина


Сайт:
http://www.microsoft.com/ukr/ua/

Microsoft Украина Украинское подразделение компании Microsoft.

Ищите нас в интернетах!

Комментарии

Свежие вакансии