我知道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中使用
答案 0 :(得分:4)
由于B是Unity3D游戏,您需要做的就是编译3个不同版本的A并将它们放在适当的default folders for the plugin inspector中。
我们假设UNITY_EDITOR
,UNITY_WSA
和UNITY_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的东西。
话虽如此,可能有理由做你正在尝试做的事情,例如没有将实施细节泄露给使用你的应用程序的竞争公司。