Is it possible to keep precompiled symbols in C# assemblies for use in a referencing program?

孤者浪人 提交于 2019-12-25 09:08:04

问题


I know that the C# preprocessor will generally eliminate the precompiled symbols. Can the rule be broken a bit?

For example, I have a C# dll A, which I wanna use in another C# program B. In B I have different precompiled symbols X, Y, Z. If X is defined, I need a version of A. Else if Y is defined, I need another version of A. And similar for Z. To implement this, I want to write precompiled directives in A's source code, like

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

I hope these conditions don't disappear during A's compiling and B can take use of them. Is it possible? Or what should I do to work around this?

Thanks in advance.

EDIT

Some background information. B is a Unity3D Game, and A is a common library we want to use across different games. So Both A and B relies on the assembly UnityEngine.dll. Then there is various precompiled symbols defined by U3D to indicate the current build platform, the engine's version and etc, which I want to take use of in both A and B.


回答1:


In general, you define compiler constants on a project basis. So if your shared assembly defines X and you compile it, it only contains the call to DoX(). Then you compile the actually consuming application where you define Y, but that won't affect the shared assembly.

However, compiler constants can be passed to the compiler using the command line or using XAML, and then apply to all projects that are built at the same time.

How to do so is explained in Is There anyway to #define Constant on a Solution Basis? and MSDN: How to: Declare Conditional Compilation Constants.

So that might be an option: declare them solution-wide and compile the solution as a whole. Do note that your shared assembly then only contains the call corresponding to the constant(s) defined at compile-time: you can't share that assembly with different executables compiled with different constants, because only DoX() will be called if X was declared at compile-time.

Or, rather, you dump this idea altogether and implement the proper design pattern, so the proper method will be called depending on what the caller wants, not who the caller is.

This may mean you should simply expose DoX(), DoY() and DoZ() to the caller, or let MyMethod() do something based on a passed (enum) variable, or something using a strategy pattern.

That being said, there may be reasons to do what you're trying to do, for example not leaking implementation details to competing companies who use your application.




回答2:


Being that B is a Unity3D game what you need to do is just compile your 3 different versions of A and put them in the appropriate default folders for the plugin inspector.

Instead of X, Y, and Z, lets say we have UNITY_EDITOR, UNITY_WSA, and 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
    }
}

You would need to make 3 copies of A.dll each compiled with the different setting set.

Once you have your 3 dll's you just need to put them in the correct folders in your project to be set to the proper build types automaticly. Your file structure should look like

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

You don't have to use that structure, but using those folders make them automatically get picked up by the inspector for the correct build types.



来源:https://stackoverflow.com/questions/38771195/is-it-possible-to-keep-precompiled-symbols-in-c-sharp-assemblies-for-use-in-a-re

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!