2015-10-07 2 views
1

У меня есть C++ код, который использует такой подход:Проблемы, связанные с использованием #ifdefs в C#

#if defined(CONSTANT) 
.. 
// Some code 
#else 
// Some other code 

мне сказали, что я могу использовать аналогичный подход в C# -из мне нужно переписать этот C++ проект на C#. Но есть одна проблема. Из документации, которую я видел, что в C#, если я использую

#define CONSTANT 

это видно только в файле, где он был объявлен.

Но я не хочу этого. Я хочу, чтобы этот CONSTANT был виден во всех классах? Я думаю, что одним из решений является объявление таких констант в настройках проекта и т. Д., Но вот мой первый вопрос: В этом случае мне нужно отправить дополнительный файл с моей DLL? Или эти константы будут встроены в DLL?

И, наконец, чтобы избежать описанных выше проблем, я думаю о подходе к использованию только открытых значений const в C#. Как

if(Globals.SomeConstant == SOMEVALUE) 
// Do this 
else 
// Do smth else 

А затем в зависимости от конфигурации обращу значение по умолчанию при объявлении Globals.SomeConstant до значения мне нужно, скомпилировать DLL и отправить его. Звучит ли это нормально и будет ли это работать так? Будут ли назначаться значения по умолчанию и правильно читать внутри DLL-методов? (они будут работать как # ifdefs?)

Я знаю, что мне нужно будет перекомпилировать, чтобы изменить код, но это нормально.

+2

Вы можете определить глобальные определяет в свойствах проекта для данного проекта. Свойства> Сборка> Условные символы компиляции Определенные символы там не будут внедрены, скомпилированный код будет следовать другому пути в компиляторе, символы компиляции - это «время компиляции», а не время выполнения. Второй метод, который вы опубликовали, не эквивалентен '# ifdef', и я бы избегал такого подхода. –

+0

Они просто константы времени компиляции, ничто не будет встроено в вашу DLL. –

+0

@RonBeyer: Моя точка зрения заключается в том, что я определяю эти константы в свойствах проекта, как вы упомянули, мне нужно отправить что-либо дополнительно с моей DLL? Или просто моя DLL будет в порядке? и в зависимости от того, какие символы я определил в свойствах, я могу соответственно использовать #ifdefs? –

ответ

1

Если вы используете Visual Studio, достаточно просто выполнить предпроцессорные директивы.

  1. Выбор проект
  2. Свойство
  3. Построить
  4. На «условной компиляции символов» положить разыскиваемый символ, и вы должны иметь доступ во всех сборках

Если вы не используете видео Студия просто следуйте this topic.

Для ознакомления с инструкциями препроцессора вы можете перейти на сайт Tutorialspoint C#.

Чтобы написать код в C# с использованием C подход ++ вы можете использовать следующий синтаксис:

#define Name_Value 

#if (Name_value) 
{ 
    //code 
} 

Если это не соответствует вашим потребностям вы можете пойти с файлом конфигурации, где вы можете сложить во всех ваших имя ключа - значение и доступ к ним по адресу ConfigurationManger.AppSettings["Key"]

Другой способ создания глобальной сети enum и присвоение значений.

public enum DemoEnum 
{ 
    Name = Value 
} 

if(passedEnum == DemoEnum.Name) 
{ 
    // code 
} 

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

Используя свойства readonly, вы можете переключать значения «const» в своем подходе.

public class Global 
{ 
    public readonly string Name; 

    public Global() 
    { 
     if(condition) 
      Name = 10; 
     else 
      Name = 30; 
    } 
} 

Если я забыл вариант не стесняйтесь комментировать :)

+0

«Решение, которое вы дали с константами, не очень гибко, потому что если ваш код изменится, вам придется создавать новые константы, и изображение становится слишком размытым». - Можете ли вы объяснить, что вы здесь имеете в виду? Я думаю о public const, потому что, если есть необходимость в перекомпиляции, это не проблема, потому что текущее решение на C++ тоже работает. Как вы думаете? –

+0

Мне сказали, что «Имейте в виду: нет гарантии, что условный символ компиляции одинаковый для всех проектов вашего решения. Это будет препятствовать повторному использованию ваших DLL другими решениями, которые хотят использовать условные символы компиляции». - Вы знаете, что это значит? –

+0

Я имел в виду глобальное const enum в основном –

2

C# не имеет «препроцессор» таким же образом, как у C/C++. И эти #define s являются «константами» - это просто «символы», которые вы можете запросить только на наличие или отсутствие. Они не оставляют следов в сборке.

Теперь, когда вы скомпилировать сборку с (или без него) треугольником #define д, то результат вполне может быть различным:

public const int I = 
#if FOO_BAR 
    42 
#else 
    43 
#endif 
; 

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

+0

«В C#, с другой стороны, сторонний код чаще всего распространяется как скомпилированная сборка. Таким образом, если вы хотите изменить способ работы кода на этой сторонней сборке, вам придется сделать это на во время выполнения «. - Не могли бы вы объяснить, что вы здесь имеете в виду? –

Смежные вопросы