是否可以在C#程序集中保留预编译符号以用于引用程序?

时间:2016-08-04 15:12:32

标签: c# unity3d .net-assembly

我知道C#预处理器通常会消除预编译的符号。这条规则能否被打破?

例如,我有一个C#dll A ,我想在另一个C#程序 B 中使用它。在 B 中,我有不同的预编译符号 X Y Z 。如果定义了 X ,我需要 A 的版本。否则,如果定义 Y ,我需要另一个版本的 A 。和 Z 类似。为了实现这一点,我想在 A 的源代码中编写预编译指令,比如

public static class MyClass
{
    public static void MyMethod()
    {
#if X
        DoX();
#elif Y
        DoY();
#elif Z
        DoZ();
#else
        DoWhatever();
#endif
    }
}

我希望这些条件在 A 的编译过程中不会消失, B 可以使用它们。可能吗?或者我应该怎么做才能解决这个问题?

提前致谢。

修改

一些背景资料。 B 是Unity3D游戏, A 是我们想要在不同游戏中使用的常见库。所以 A B 都依赖于程序集UnityEngine.dll。然后有各种预编译符号由U3D定义,以指示当前构建平台,引擎版本等,我想在 A B中使用

2 个答案:

答案 0 :(得分:4)

由于B是Unity3D游戏,您需要做的就是编译3个不同版本的A并将它们放在适当的default folders for the plugin inspector中。

我们假设UNITY_EDITORUNITY_WSAUNITY_IOS代替X,Y和Z.

public static class MyClass
{
    public static void MyMethod()
    {
#if UNITY_EDITOR
        DoX();
#elif UNITY_WSA
        DoY();
#elif UNITY_IOS
        DoZ();
#else
        DoWhatever();
#endif
    }
}

您需要制作3份A.dll副本,每个副本使用不同的设置集编译。

一旦拥有了3个dll,您只需将它们放入项目中的正确文件夹中,即可自动设置为正确的构建类型。您的文件结构应该类似于

Assets/Plugins/Editor/A.dll
Assets/Plugins/WSA/A.dll
Assets/Plugins/iOS/A.dll

您不必使用该结构,但使用这些文件夹会使检查员自动获取正确的构建类型。

答案 1 :(得分:1)

通常,您可以基于项目定义编译器常量。因此,如果您的共享程序集定义X并进行编译,则它只包含对DoX()的调用。然后编译实际消耗的应用程序,您可以在其中定义Y,但这不会影响共享程序集。

但是,编译器常量可以使用命令行或使用XAML传递给编译器,然后应用于同时构建的所有项目。

Is There anyway to #define Constant on a Solution Basis?MSDN: How to: Declare Conditional Compilation Constants中解释了如何执行此操作。

因此,这可能是一个选项:在解决方案范围内声明它们并整体编译解决方案。请注意,您的共享程序集只包含与编译时定义的常量相对应的调用:您不能与使用不同常量编译的不同可执行文件共享该程序集,因为只有DoX()将是如果在编译时声明X,则调用。

或者说,你完全抛弃这个想法并实现正确的设计模式,因此将根据调用者想要的来调用正确的方法,而不是调用者是谁

这可能意味着您只需向调用方公开DoX()DoY()DoZ(),或让MyMethod()根据传递的(枚举)变量执行某些操作,或者使用strategy pattern的东西。

话虽如此,可能有理由做你正在尝试做的事情,例如没有将实施细节泄露给使用你的应用程序的竞争公司。