C#中条件编译的替代方法

时间:2010-09-24 12:01:32

标签: c# conditional-compilation

在C#中使用条件编译代码有什么替代方法?

我有一个类,它有很多基于#ifdef的代码..过了一段时间我的代码不可读。

寻找重构技术,以提高#if defs的代码的可读性和维护性

7 个答案:

答案 0 :(得分:23)

有一件事是使用ConditionalAttribute

[Conditional("DEBUG")]
public void Foo()
{
    // Stuff
}

// This call will only be compiled into the code if the DEBUG symbol is defined
Foo();

它仍然是条件编译,但是基于属性而不是#ifdef,这使得它通常更简单。

另一种选择是在执行时使用布尔值,而不是在编译时全部执行。如果您可以向我们提供有关您要实现的目标以及如何使用条件编译的更多详细信息,那将非常有用。

答案 1 :(得分:7)

另一种方法是使用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.");
    }
}

答案 2 :(得分:6)

如果这是代码可读性问题,你可以考虑使用.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可能会变得丑陋)以及需要一定的愚蠢去文件以有效地启用/禁用该位代码。

因此,使用这种方法最终会引入比它解决的更复杂的问题,但是,根据您的代码,它可能会有所帮助吗?

答案 3 :(得分:1)

使用ConditionalAttribute将是一个开始。否则,通常可以通过反转控制和/或明智地使用工厂来处理人们经常对条件编译做的事情。

答案 4 :(得分:1)

多态性。

以与在相同条件下具有大量条件分支的任何意大利面条代码相同的方式处理它。

将差异抽象为基类或接口。

根据构建构造具体类(一个#if)。将具体对象传递给您的应用程序,然后您的应用程序调用界面上定义的方法。

答案 5 :(得分:0)

如果您使用条件编译的原因可以轻松重构,您可以考虑使用Managed Extensibility Framework根据运行时的条件动态加载代码。

答案 6 :(得分:0)

扩展Jon的答案,虽然使用ConditionalAttribute有许多限制,但有一个显着的优势。当条件为假时,省略对条件方法的调用。例如,您可以向日志系统添加100个调用,例如调试,可以有条件地从生产代码中排除。当它们被排除时,没有与调用不需要调用的方法相关的开销。使用#ifdef,您必须将每次调用包装到日志记录系统,以有条件地排除它们。

请注意,如果重新编译条件方法的调用方,则此方法仅适用于程序集。