在 C# 中使用条件编译代码的替代方法是什么?
我有一个类有很多基于# ifdef 的代码。一段时间后我的代码不可读。
寻找重构技术以用于更好的可读性和维护具有许多#if
defs的代码
在 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)构建具体类。将具体对象传递给您的应用程序,然后您的应用程序调用接口上定义的方法。
如果您使用条件编译的原因可以轻松重构,您可以考虑使用托管可扩展性框架在运行时根据条件动态加载代码。
扩展乔恩的答案,虽然使用 有许多限制ConditionalAttribute
,但有一个显着的优势。当条件为假时,将省略对条件方法的调用。例如,您可以向日志系统添加 100 次调用,例如用于调试,这些调用可以有条件地从生产代码中排除。当它们被排除时,调用不需要调用的方法不会产生任何开销。使用#ifdef,您必须包装对日志系统的每次调用以有条件地排除它们。
请注意,如果条件方法的调用者被重新编译,这仅适用于程序集。