是否可以在 C# 程序集中保留预编译符号以用于引用程序?
Is it possible to keep precompiled symbols in C# assemblies for use in a referencing program?
我知道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[中使用它们=44=].
通常,您可以在项目基础上定义编译器常量。因此,如果您的共享程序集定义了 X
并且您编译了它,它只包含对 DoX()
的调用。然后编译您定义 Y
的实际使用的应用程序,但这不会影响共享程序集。
但是,可以使用命令行或使用 XAML 将编译器常量传递给编译器,然后应用于同时构建的所有项目。
Is There anyway to #define Constant on a Solution Basis? and MSDN: How to: Declare Conditional Compilation Constants 中解释了如何执行此操作。
所以这可能是一个选择:在解决方案范围内声明它们并将解决方案编译为一个整体。请注意,您的共享程序集仅包含与编译时定义的常量相对应的调用:您不能与使用不同常量编译的不同可执行文件共享该程序集,因为如果只有 DoX()
将被调用X
是在编译时声明的。
或者,更确切地说,您完全抛弃了这个想法并实施了正确的设计模式,因此将根据调用者想要的而不是[=35=调用正确的方法]来电者是谁.
这可能意味着您应该简单地向调用者公开 DoX()
、DoY()
和 DoZ()
,或者让 MyMethod()
根据传递的(枚举)变量做一些事情, 或者使用 strategy pattern.
的东西
话虽这么说,但您尝试做的事情可能是有原因的,例如,不要将实施细节泄露给使用您的应用程序的竞争公司。
因为 B 是一个 Unity3D 游戏,你需要做的只是编译你的 3 个不同版本的 A 并将它们放在适当的 default folders for the plugin inspector.
而不是 X、Y 和 Z,假设我们有 UNITY_EDITOR
、UNITY_WSA
和 UNITY_IOS
。
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
您不必使用该结构,但使用这些文件夹会使检查员自动选择正确的构建类型。
我知道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[中使用它们=44=].
通常,您可以在项目基础上定义编译器常量。因此,如果您的共享程序集定义了 X
并且您编译了它,它只包含对 DoX()
的调用。然后编译您定义 Y
的实际使用的应用程序,但这不会影响共享程序集。
但是,可以使用命令行或使用 XAML 将编译器常量传递给编译器,然后应用于同时构建的所有项目。
Is There anyway to #define Constant on a Solution Basis? and MSDN: How to: Declare Conditional Compilation Constants 中解释了如何执行此操作。
所以这可能是一个选择:在解决方案范围内声明它们并将解决方案编译为一个整体。请注意,您的共享程序集仅包含与编译时定义的常量相对应的调用:您不能与使用不同常量编译的不同可执行文件共享该程序集,因为如果只有 DoX()
将被调用X
是在编译时声明的。
或者,更确切地说,您完全抛弃了这个想法并实施了正确的设计模式,因此将根据调用者想要的而不是[=35=调用正确的方法]来电者是谁.
这可能意味着您应该简单地向调用者公开 DoX()
、DoY()
和 DoZ()
,或者让 MyMethod()
根据传递的(枚举)变量做一些事情, 或者使用 strategy pattern.
话虽这么说,但您尝试做的事情可能是有原因的,例如,不要将实施细节泄露给使用您的应用程序的竞争公司。
因为 B 是一个 Unity3D 游戏,你需要做的只是编译你的 3 个不同版本的 A 并将它们放在适当的 default folders for the plugin inspector.
而不是 X、Y 和 Z,假设我们有 UNITY_EDITOR
、UNITY_WSA
和 UNITY_IOS
。
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
您不必使用该结构,但使用这些文件夹会使检查员自动选择正确的构建类型。