简体   繁体   English

在C#中删除预处理器分支

[英]Removing preprocessor branching in C#

I am refactoring some source code and got a task to remove preprocessor compiling. 我正在重构一些源代码,并获得了删除预处理器编译的任务。 I have now searched internet for some days, but haven't found any good idea how to do that. 我现在已经在互联网上搜索了几天,但是还没有找到如何执行此操作的好主意。 I am also quite new to C#. 我对C#也很陌生。

So the problem is following, I have different interfaces (classes) for every device and "ControlLogic" class needs to use only one of them at the time. 因此出现了问题,每个设备都有不同的接口(类),并且“ ControlLogic”类当时只需要使用其中一个即可。 Device is chosen on program run-time. 在程序运行时选择设备。 So far "device" variable (also used globally) is used in a lot of places and considering renaming that doesn't make sense to me. 到目前为止,“ device”变量(也在全球范围内使用)已在很多地方使用,并且考虑到重命名对我来说没有意义。 Also all device interfaces (classes) are derived from base class, but interface classes does implement different methods for them. 同样,所有设备接口(类)都派生自基类,但是接口类确实为它们实现了不同的方法。

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.....
}

So what is the best way to remove preprocessor compiling? 那么删除预处理器编译的最佳方法是什么?

I've faced with a similar task a few months ago: large C# code base and extensive preprocessor directives usage. 几个月前,我面临着类似的任务:庞大的C#代码库和广泛的预处理器指令用法。 Manual refactoring looked like a long boring monkey job there. 手动重构看起来像是一个漫长而无聊的猴子工作。 I've failed with unifdef , sunifdef and coan C tools because of C# syntax specifics like #region and some others. 我由于unifdefsunifdefcoan C工具而失败,因为#region等一些C#语法细节。 In the long run I've made my own tool undefine . 从长远来看,我已经使自己的工具变得不确定 It uses regexp to parse the preprocessor directives and sympy python library to simplify logical expression. 它使用regexp解析预处理器指令,并使用sympy python库简化逻辑表达式。 It works good for me on large 10M lines code base. 在1000万行的大型代码库上,它对我很有用。

I understand that the three device types do not have a common base class or interface. 我知道这三种设备类型没有通用的基类或接口。 You cannot just pick one of the three at runtime and type all variables with a base type. 您不能只在运行时选择三个变量之一并使用基本类型键入所有变量。

Here are a few options: 以下是一些选择:

  1. Find a way to aa common base type . 找到一种常见的基本类型的方法
  2. If you cannot modify the classes (or it would be inappropriate for some reason) write a wrapper . 如果您不能修改类(或者由于某些原因而不合适),请编写包装器 That wrapper can have any structure you like. 该包装器可以具有您喜欢的任何结构。 You could have one wrapper per device class with a common base type. 每个设备类可以有一个具有通用基本类型的包装器。
  3. Use dynamic . 使用dynamic This can be a quick fix at the cost of less tooling help (less autocompletion, less documentation at hand, less quick static error checking). 这可以通过减少工具帮助(减少自动完成,减少手头的文档,减少快速的静态错误检查)的代价来快速解决。

Using #if to solve this problem is very unusual. 使用#if解决此问题非常罕见。 It is problematic because the amount of testing to even make sure the code compiles has now tripled. 这是有问题的,因为现在甚至可以确保代码编译的测试量增加了两倍。 You also need multiple binaries. 您还需要多个二进制文件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM