Альтернативы условной компиляции в С#
Какова альтернатива наличию кода с условной компиляцией в С#?
У меня есть класс, у которого есть много кода, основанного на # ifdef.. После моего кода мой код не читается.
Поиск методов рефакторинга для более удобного чтения и обслуживания кода со многими #if
defs
Ответы
Ответ 1
Одно дело - ConditionalAttribute
:
[Conditional("DEBUG")]
public void Foo()
{
// Stuff
}
// This call will only be compiled into the code if the DEBUG symbol is defined
Foo();
Это условная компиляция, но на основе атрибутов, а не #ifdef
, что делает ее более простой.
Другой альтернативой является просто использовать логические значения во время выполнения, а не делать все это во время компиляции. Если бы вы могли дать нам более подробную информацию о том, чего вы пытаетесь достичь, и как вы используете условную компиляцию, это было бы полезно.
Ответ 2
Альтернативой является использование ConditionalAttribute. Условный атрибут работает аналогичным образом.
#define TRACE_ON
using System;
using System.Diagnostics;
public class Trace
{
[Conditional("TRACE_ON")]
public static void Msg(string msg)
{
Console.WriteLine(msg);
}
}
public class ProgramClass
{
static void Main()
{
Trace.Msg("Now in Main...");
Console.WriteLine("Done.");
}
}
Ответ 3
Если это проблема чтения кода, вы можете подумать об использовании классификатора классов .Net partial class и поместить условный код в отдельные файлы, так что, возможно, у вас может быть что-то вроде этого...
foo.cs:
public partial class Foo
{
// Shared Behavior
}
foo.Debug.cs:
#if DEBUG
public partial class Foo
{
// debug Behavior
}
#endif
foo.bar.cs:
#define BAR
#if BAR
public partial class Foo
{
// special "BAR" Behavior
}
#endif
Я не уверен, можете ли вы определить свои условные условия за пределами файла кода, поэтому сделать что-то подобное может уменьшить гибкость условных определений (например, вы не сможете создать условную ветвь против BAR в, скажем, главный файл, и необходимость поддерживать несколько определенных BAR может стать уродливой), а также потребовать некоторого уклонения пойти в файлы, чтобы эффективно включить/отключить этот бит кода.
Итак, использование этого подхода может привести к появлению большего количества осложнений, чем оно решает, но, в зависимости от вашего кода, может быть, это может быть полезно?
Ответ 4
Использование ConditionalAttribute будет началом. В противном случае, довольно много того, что люди часто делают с условной компиляцией, обычно можно обрабатывать путем инверсии управления и/или разумного использования заводов.
Ответ 5
полиморфизм.
Подходите к нему так же, как и любой код спагетти с большим количеством условных ветвей в одном и том же состоянии.
Проанализируйте различия в базовом классе или интерфейсе.
Построить конкретный класс в зависимости от сборки (один #if). Передайте конкретный объект в свое приложение, а затем ваше приложение вызывает методы, определенные на интерфейсе.
Ответ 6
ЕСЛИ причина, по которой вы используете условную компиляцию, может быть легко реорганизована, вы можете использовать Managed Extensibility Framework для динамического загрузки кода на основе условий во время выполнения.
Ответ 7
Расширение ответа на Jon, хотя существует ряд ограничений на использование ConditionalAttribute
, есть существенное преимущество. Когда условие ложно, вызовы условного метода опущены. Например, вы можете добавить 100 вызовов в систему регистрации, например, для отладки, которые могут быть условно исключены из производственного кода. Когда они исключены, нет накладных расходов, связанных с вызовом метода, который не нужно вызывать. Используя #ifdef, вам придется обернуть каждый вызов в систему ведения журнала, чтобы условно исключить их.
Обратите внимание, что это работает только через сборки, если вызывающий объект условного метода повторно скомпилирован.