如何通过预处理器宏区分Android、WPF、WinForm项目编译代码?
我有一个在多个项目间共享的Extension类,涉及Android(Xamarin/.NET MAUI)、WinForm、WPF应用,甚至包含WPF窗口的WinForm项目。不同平台存在API差异:Android不支持System.Data.SqlClient,WinForm项目若无手动引用PresentationCore等DLL则无法使用System.Windows相关扩展。希望通过编译时预处理器宏启用/禁用对应平台代码,替代手动注释操作,期望实现类似如下代码效果:
#if !(ANDROID_RUNTIME) public static string SqlDataReaderStringExt(this SqlDataReader reader, int i) { ... } #endif #if WPF_RUNTIME .... #endif #if WINFORM_RUNTIME .... #endif
各平台可用的预处理器宏
直接用以下宏就能实现编译时的平台代码隔离,无需自定义宏(部分旧框架需手动添加):
Android(Xamarin/.NET MAUI):
Xamarin.Android默认带__ANDROID__宏,.NET MAUI Android默认带ANDROID宏。兼容两种场景的话,判断条件可以写#if ANDROID || __ANDROID__。WinForms:
.NET 5+的WinForms项目自动生成WINDOWS_FORMS宏;.NET Framework的WinForms需要手动去项目属性→生成→预处理器指令中添加WINDOWS_FORMS。统一用这个宏判断即可覆盖新旧框架。WPF:
.NET Framework的WPF自动生成WPF宏;.NET 5+的WPF自动生成WINDOWS_WPF宏。如果要兼容所有WPF项目,判断条件可以写#if WPF || WINDOWS_WPF。WinForm嵌套WPF窗口的混合项目:
直接在项目属性的预处理器指令里添加WINDOWS_FORMS;WINDOWS_WPF,这样代码里的WinForms和WPF宏都会生效。
调整后的示例代码
// Android平台不编译该SqlClient扩展 #if !(ANDROID || __ANDROID__) public static string SqlDataReaderStringExt(this SqlDataReader reader, int i) { // 你的实现逻辑 } #endif // 仅WPF平台编译该扩展 #if WPF || WINDOWS_WPF public static void WpfControlExtension(this System.Windows.Controls.Control control) { // WPF专属逻辑 } #endif // 仅WinForms平台编译该扩展 #if WINDOWS_FORMS public static void WinFormControlExtension(this System.Windows.Forms.Control control) { // WinForms专属逻辑 } #endif
内容的提问来源于stack exchange,提问作者Mike97

