2016-08-04 14 views
0

我知道C#預處理器通常會消除預編譯的符號。規則是否可以被打破一點?是否有可能在C#程序集中保留用於引用程序的預編譯符號?

例如,我有一個C#DLL ,我想在另一個C#程序使用。在B我有不同的預編譯符號X,Y,Z。如果定義了X,我需要版本A。否則,如果Y被定義,我需要另一個版本的A。和Z類似。爲了實現這一點,我想寫預編譯指令中一個的源代碼,像

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

我希望這些條件中一個不會消失的編譯和可以使用他們。可能嗎?或者我該怎麼做才能解決這個問題?

在此先感謝。

編輯

一些背景信息。 B是Unity3D遊戲,A是我們希望在不同遊戲中使用的常用庫。所以兩個AB依靠程序集UnityEngine.dll。然後有由U3D定義的各種預編譯符號來表示當前構建平臺,引擎版本等,我想在AB中使用這些符號。

+0

您打算購買3份A.dll嗎? A.X.dll,A.Y.dll和A.Z.dll? –

+0

像'#if'這樣的指令是用於條件編譯的。如果您希望* A *的行爲與其他程序中建立的條件不同,而不重新編譯* A *,那麼'#if'對於工作來說就是錯誤的工具。你有沒有考慮過像[工廠方法模式](https://en.wikipedia.org/wiki/Factory_method_pattern)呢? –

+0

@ScottChamberlain我希望不會。如果我這樣做,我不能讓_B_選擇使用哪個_A_,可以嗎? –

回答

1

通常,您可以在項目的基礎上定義編譯器常量。所以如果你的共享程序集定義了X並且你編譯它,它只包含對DoX()的調用。然後編譯實際使用的應用程序,在其中定義Y,但這不會影響共享程序集。

但是,編譯器常量可以使用命令行或使用XAML傳遞給編譯器,然後應用於同時構建的所有項目。

Is There anyway to #define Constant on a Solution Basis?MSDN: How to: Declare Conditional Compilation Constants中解釋瞭如何實現。

因此,這可能是一個選擇:在解決方案範圍內聲明它們並編譯整個解決方案。請注意,共享程序集僅包含與編譯時定義的常量相對應的調用:不能共享該程序集,其中包含使用不同常量編譯的不同可執行文件,因爲如果X被聲明爲「0」,則只會調用DoX()編譯時間。

或者說,你完全轉儲這個想法,並實施適當的設計模式,所以正確的方法將根據叫什麼呼叫者想要,不誰來電者是

這可能意味着你應該簡單地揭露DoX()DoY()DoZ()給調用者,或者讓MyMethod()做基礎上通過(ENUM)可變的東西,或者使用strategy pattern東西。

也就是說,可能有理由去做你正在嘗試做的事情,例如不要將實施細節泄露給使用你的應用程序的競爭公司。

+0

非常感謝您的詳細解釋和鏈接。所以我想在我的情況下,建立不同版本的dll是明智的。你是對的。我們不想泄漏實現細節,事實上我們不能在Unity3D的情況下將_A_和_B_放在一起。 –

+1

@ user1187195 with unity你不需要B來檢查符號,所有重要的是你放入A和B的文件夾。請參閱[此統一手冊頁面]的默認設置部分(http://docs.unity3d.com/Manual/PluginInspector.html)。 (實際上這個文件夾也不重要,你可以在插件檢查器中更改dll的使用平臺,該文件夾只是在檢查器中設置一些默認值) –

3

由於B是Unity3D遊戲,你需要做的只是編譯你的3個不同版本的A,並把它們放在合適的default folders for the plugin inspector

代替X,Y和Z,可以說我們有UNITY_EDITOR,UNITY_WSAUNITY_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 

您不必使用結構,但使用這些文件夾使它們自動檢查員正確的構建類型得到回升。

相關問題