簡體   English   中英

在 C# 中如何安排代碼在編譯時運行

[英]How to arrange for code to run at compile time in C#

是否有可能在編譯時執行一些代碼?

例如,我想檢查動態對象的請求方法是否存在於泛型類的參數類型中。

 // This code has no actual purpose, just as an example
 public class Sample<T>
 {
     public Sample<T>(T instance)
     {
         foo = Value = instance;
         /* adding some extra code(e.g. logging) to the methods of T, by
inserting a "M" in front of the method names of T */
     }

     public T Value { get; }
     public dynamic foo { get; }
 }

如何/可以使用它

var foo = new Sample<string>("hey");
foo.MSubstring(0,0);

現在我想知道是否有可能在編譯時執行代碼,例如,在運行之前拋出異常foo.MgetSize()在 T 中不存在。

(這個問題只是關於如何在編譯時執行代碼,這個示例不是真正的問題。)

我沒有計划如何做到這一點。 也許使用那些#if - 的東西?

是的,可以在構建時執行代碼。 畢竟,構建程序的工具本身就是代碼。

您要問的是如何自定義構建過程並在此過程中執行一些額外的邏輯。 您將如何執行此操作取決於您使用的實際工具 - 例如,對於 Visual Studio 和 MSBuild 系統,您可以參考有關自定義構建步驟和構建事件MSDN 文檔

您的自定義構建工具是什么樣的取決於它將在流程的哪個部分啟動。如果它與源代碼一起工作,它需要能夠解析 C# 源代碼(可能還有 Visual Studio 項目文件)。 如果它通過驗證發出的程序集(在典型構建過程結束時生成的二進制文件)來工作,它可以簡單地使用反射來檢測您想要的錯誤。 我想說后者更方便。

理論上,您可以使用T4進行編譯時檢查。

另一種方法是使用支持編譯時宏的語言。 例如, NemerleBoo

也許你可以使用Roslyn 但僅限於 C# 6。

在 C# 中,您可以運行一些您剛剛在 Visual Studio 的“構建后”步驟中編譯的代碼。

您也許可以使用 Post# 之類的工具,通過創建執行您想要的檢查的屬性來執行您想要的操作。 請參閱: https : //www.postsharp.net/product/how-it-works

在其他語言中,例如 Jai,您可以輕松完成此操作。 請參閱任意編譯時代碼執行

某個函數可能存在也可能不存在的場景有點粗略。 最好在你的接口中包含一個Convert方法,對象本身可以告訴你它是否實現了該功能,並返回一個具有適當接口的對象,如果沒有,則返回 null。

雖然,它可以用預處理器完成,但我不推薦它。 您所描述的場景意味着您將包含一個為對象定義該方法的標頭,或者一個沒有定義該方法的標頭。 你沒有得到真正的動態。 所以在標題中,使用一個

#define HASMETHOD

並在您的執行人中使用:

#ifdef HASMETHOD
   foo.MSubstring(0, 0);
#endif

但同樣,我強烈建議不要這樣做。 使用在運行時調用的方法來確定返回要調用的接口。

根據定義,您不能在編譯時執行代碼。 但是,您可以在加載時(實際上在創建第一個實例或引用任何靜態成員之前)使用靜態構造函數執行代碼:

鏈接到 msdn

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM