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

发布于 2024-09-24 22:27:43 字数 137 浏览 2 评论 0原文

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

我有一个类,其中有很多基于 # ifdef 的代码。一段时间后,我的代码变得不可读。

寻找重构技术,以提高具有许多 #if def 的代码的可读性和维护性

What is the alternative to having code with conditional compilation in C#?

I have a class that has lots of code that is based on # ifdef .. After sometime my code is unreadable.

Looking for refactoring techniques to use for better readability and maintenance of code with many #if defs

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

挽清梦 2024-10-01 22:27:43

一件事是使用 ConditionalAttribute< /a>:

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

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

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

另一种选择是在执行时简单地使用布尔值,而不是在编译时执行所有操作。如果您可以向我们提供有关您想要实现的目标以及如何使用条件编译的更多详细信息,那将会很有用。

One thing is to use the ConditionalAttribute:

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

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

It's still conditional compilation, but based on attributes rather than #ifdef, which makes it generally simpler.

Another alternative is simply to use Boolean values at execution time, instead of doing it all at compile time. If you could give us more details of what you're trying to achieve and how you're using conditional compilation, that would be useful.

萧瑟寒风 2024-10-01 22:27:43

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

An alternative is to use the ConditionalAttribute. The conditional attribute works in a similar way.

#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.");
    }
}
独自唱情﹋歌 2024-10-01 22:27:43

如果是代码可读性问题,您可以考虑使用 .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 可能会变得丑陋)并且需要一定的勤奋才能进行文件来有效地启用/禁用该代码段。

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

If it's a code-readability issue, you might consider using .Net's partial class qualifier and put the conditional code in separate files, so maybe you could have something like this...

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

I'm not sure whether or not you can define your conditionals outside of the code file though, so doing something like this might reduce the flexibility of the conditional definitions (e.g. you might not be able to create a conditional branch against BAR in, say, the main file, and having to maintain multiple defined BARs could get ugly) as well as require a certain dilligence to go to the files to effectively enable/disable that bit of code.

So, using this approach might end up introducing more complications than it solves, but, depending on your code, maybe it could be helpful?

空袭的梦i 2024-10-01 22:27:43

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

Using ConditionalAttribute would be a start. Otherwise, quite a bit of what folks often do with conditional compilation can usually be handled by inversion of control and/or judicious use of factories.

时光沙漏 2024-10-01 22:27:43

多态性。

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

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

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

Polymorphism.

Approach it the same way as you would any spaghetti code with lots of conditional branches on the same condition.

Abstract out the differences into a base class or interface.

Construct the concrete class depending on build (one #if). Pass the concrete object to your App, and then your app calls the methods defined on the interface.

几味少女 2024-10-01 22:27:43

如果您使用条件编译的原因可以轻松重构,您可以考虑使用托管扩展性框架来加载根据运行时的条件动态编码。

IF the reason you are using conditional compilation can be easily refactored, you might consider using the Managed Extensibility Framework to load the code dynamically based on conditions at runtime.

若相惜即相离 2024-10-01 22:27:43

扩展乔恩的答案,虽然使用 ConditionalAttribute 有许多限制,但有一个显着的优势。当条件为 false 时,将省略对条件方法的调用。例如,您可以向日志系统添加数百个调用(例如用于调试),这些调用可以有条件地从生产代码中排除。当它们被排除时,就不会产生与调用不需要调用的方法相关的开销。使用#ifdef,您必须包装对日志系统的每个调用以有条件地排除它们。

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

Expanding on Jon's answer, while there a number of limitations on using the ConditionalAttribute, there is a significant advantage. When the condition is false, the calls to conditional method are omitted. For example, you can add 100's of calls to a logging system, say for debugging, that can be conditionally excluded from the production code. When they are excluded, there is no overhead associated with calling a method which does not need to be called. Using #ifdef, you would have to wrap every call to the logging system to conditionally exclude them.

Note this only works across assemblies, if the caller of the conditional method is re-compiled.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文