C#中条件编译的替代方案
在C#中使用条件编译代码的替代方法是什么?
我有一个类,有很多基于#ifdef的代码..过了一段时间我的代码是不可读的。
寻找重构技术,以便使用许多#if
defs来提高代码的可读性和维护性
一件事是使用ConditionalAttribute
:
[Conditional("DEBUG")] public void Foo() { // Stuff } // This call will only be compiled into the code if the DEBUG symbol is defined Foo();
它仍然是条件编译,但基于属性而不是#ifdef
,这使得它通常更简单。
另一种方法是在执行时使用布尔值,而不是在编译时全部执行。 如果您可以向我们提供有关您要实现的内容以及如何使用条件编译的更多详细信息,那将非常有用。
另一种方法是使用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."); } }
如果这是代码可读性问题,你可以考虑使用.Net的部分类限定符并将条件代码放在单独的文件中,所以也许你可以有这样的东西……
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可能变得丑陋)以及需要一定的愚蠢去文件以有效地启用/禁用该位代码。
因此,使用这种方法可能最终会引入比它解决的更复杂的问题,但是,根据您的代码,它可能会有所帮助吗?
使用ConditionalAttribute将是一个开始。 否则,通常可以通过反转控制和/或明智地使用工厂来处理人们经常对条件编译做的事情。
多态性。
以与在相同条件下具有大量条件分支的任何意大利面条代码相同的方式处理它。
将差异抽象为基类或接口。
根据构建构造具体类(一个#if)。 将具体对象传递给您的应用程序,然后您的应用程序调用界面上定义的方法。
如果您使用条件编译的原因可以轻松重构,您可以考虑使用Managed Extensibility Framework根据运行时的条件动态加载代码。
扩展Jon的答案,虽然使用ConditionalAttribute
存在许多限制,但是有一个显着的优点。 当条件为假时,省略对条件方法的调用。 例如,您可以向日志系统添加100个调用,例如调试,可以从生产代码中有条件地排除。 当它们被排除时,调用不需要调用的方法没有任何开销。 使用#ifdef,您必须将每次调用包装到日志系统,以有条件地排除它们。
请注意,如果重新编译条件方法的调用方,则此方法仅适用于程序集。