C# 在C语言中消除预处理器分支#

C# 在C语言中消除预处理器分支#,c#,c-preprocessor,C#,C Preprocessor,我正在重构一些源代码,任务是删除预处理器编译。我现在已经在互联网上搜索了几天,但还没有找到任何好办法。我对C#也很陌生 所以问题是,我为每个设备提供了不同的接口(类),而“ControlLogic”类在同一时间只需要使用其中的一个。在程序运行时选择设备。 到目前为止,“设备”变量(也在全球范围内使用)在很多地方都被使用,考虑重命名对我来说毫无意义。此外,所有设备接口(类)都是从基类派生的,但接口类确实为它们实现了不同的方法 public class ControlLogic { #if FIRS

我正在重构一些源代码,任务是删除预处理器编译。我现在已经在互联网上搜索了几天,但还没有找到任何好办法。我对C#也很陌生

所以问题是,我为每个设备提供了不同的接口(类),而“ControlLogic”类在同一时间只需要使用其中的一个。在程序运行时选择设备。 到目前为止,“设备”变量(也在全球范围内使用)在很多地方都被使用,考虑重命名对我来说毫无意义。此外,所有设备接口(类)都是从基类派生的,但接口类确实为它们实现了不同的方法

public class ControlLogic
{
#if FIRST_DEVICE
        public FirstDeviceInterace device = null;
#elif SECOND_DEVICE
        public SecondDeviceInterface device = null;
#elif THIRD_DEVICE
        public ThirdDeviceInterface device = null;
#endif

// One example method
public void startDevice()
{
    if (device != null)
    {
#if (FIRST_DEVICE || SECOND_DEVICE)
         device.startDevice();
#endif

#if THIRD_DEVICE
         device.startThirdDevice();
#endif
     }
}

// More code.....
}

那么,删除预处理器编译的最佳方法是什么呢?

我知道这三种设备类型没有通用的基类或接口。您不能在运行时仅从三个变量中选择一个,然后使用基类型键入所有变量

以下是一些选项:

  • 找到一种方法来创建一个公共基类型
  • 如果无法修改类(或者由于某些原因不合适),请编写一个包装器。那个包装可以有任何你喜欢的结构。每个设备类可以有一个具有公共基类型的包装器
  • 使用
    动态
    。这可能是一个快速修复,代价是工具帮助更少(自动完成更少、手头文档更少、静态错误检查更少)

  • 使用
    #if
    来解决这个问题是非常不寻常的。这是有问题的,因为即使是确保代码编译的测试量现在也增加了三倍。您还需要多个二进制文件。

    几个月前,我遇到了一个类似的任务:大型C#代码库和大量预处理器指令的使用。在那里,手工重构看起来像是一项冗长乏味的猴子工作。
    我在使用unifdefsunifdefcoanC工具时失败了,因为C的语法细节,如#region和其他一些。从长远来看,我已经有了自己的工具。它使用regexp解析预处理器指令,并使用Symphy python库简化逻辑表达式。它适用于大型10M行代码库。

    关于
    firstDeviceInterface
    和其他设备,您能告诉我们什么?您可以更改这些代码吗?您有一个程序,它打算与某些特定的设备一起工作,并在编译时做出决定。如果要删除编译时分支,请使程序足够智能,以便在运行时识别设备类型,以便同一程序可以使用任何受支持的设备。您可以保留类成员变量,例如设备类型,而不是编译时常量。您应该从抽象基类开始,并找到通用性。StartDevice()已经是您的第一个虚拟方法,当然还有更多。是的,我可以更改FirstDeviceInterface和其他接口。实际上,设备是在运行时被识别的,我有一个全局变量可以用于此。但问题是我如何根据这一点选择特定的设备接口(类)?你不认为OP在提供完整的解决方案之前应该有机会澄清吗?@Henkholtman你可能是对的。另一方面,这个答案将对许多未来的游客有用。这里有很多案例。你好!实际上,这三种设备类型(实际上还有很多)都有共同的基类,但每种类型都有一些其他设备类型没有的额外方法。