.NET MAUI中如何无重复、无条件编译共享iOS与Mac代码?
解决MAUI中Mac Catalyst与iOS共享Partial类的问题
问题背景
我在MAUI项目中为各平台定义了同名同命名空间的partial类,其中包含initialize方法,共享上下文会调用该方法。Android和Windows平台的实现已完成,但Mac Catalyst与iOS的实现代码完全一致,不想在两个平台文件夹中重复编写。
按照文件夹多目标编译的方式创建了MaciOS文件夹存放共享实现后,出现两个问题:
- 共享上下文提示iOS和Mac平台无该partial类的实现
MaciOS文件夹中的类被标记为"Miscellaneous Files",没有智能提示,Visual Studio也不显示关联的平台
当前项目的folder-based multi-targeting配置如下:
<!-- Android --> <ItemGroup Condition="$(TargetFramework.StartsWith('net8.0-android')) != true"> <Compile Remove="**\Android\**\*.cs" /> <None Include="**\Android\**\*.cs" Exclude="$(DefaultItemExcludes);$(DefaultExcludesInProjectFolder)" /> </ItemGroup> <!-- Both iOS and Mac Catalyst --> <ItemGroup Condition="$(TargetFramework.StartsWith('net8.0-ios')) != true AND $(TargetFramework.StartsWith('net8.0-maccatalyst')) != true"> <Compile Remove="**\MaciOS\**\*.cs" /> <None Include="**\MaciOS\**\*.cs" Exclude="$(DefaultItemExcludes);$(DefaultExcludesInProjectFolder)" /> </ItemGroup> <!-- iOS --> <ItemGroup Condition="$(TargetFramework.StartsWith('net8.0-ios')) != true"> <Compile Remove="**\iOS\**\*.cs" /> <None Include="**\iOS\**\*.cs" Exclude="$(DefaultItemExcludes);$(DefaultExcludesInProjectFolder)" /> </ItemGroup> <!-- Mac Catalyst --> <ItemGroup Condition="$(TargetFramework.StartsWith('net8.0-maccatalyst')) != true"> <Compile Remove="**\MacCatalyst\**\*.cs" /> <None Include="**\MacCatalyst\**\*.cs" Exclude="$(DefaultItemExcludes);$(DefaultExcludesInProjectFolder)" /> </ItemGroup> <!-- Windows --> <ItemGroup Condition="$(TargetFramework.Contains('-windows')) != true"> <Compile Remove="**\Windows\**\*.cs" /> <None Include="**\Windows\**\*.cs" Exclude="$(DefaultItemExcludes);$(DefaultExcludesInProjectFolder)" /> </ItemGroup>
解决方案
1. 修正多目标编译配置逻辑
原配置的条件判断逻辑易出错,改为主动针对iOS和Mac Catalyst平台包含MaciOS文件夹的编译项,替换原有的MaciOS相关配置:
<!-- MaciOS 共享代码:仅在iOS和Mac Catalyst平台编译 --> <ItemGroup> <Compile Remove="**\MaciOS\**\*.cs" /> <None Include="**\MaciOS\**\*.cs" Exclude="$(DefaultItemExcludes);$(DefaultExcludesInProjectFolder)" /> </ItemGroup> <ItemGroup Condition="$(TargetFramework.StartsWith('net8.0-ios')) OR $(TargetFramework.StartsWith('net8.0-maccatalyst'))"> <Compile Include="**\MaciOS\**\*.cs" /> <None Remove="**\MaciOS\**\*.cs" /> </ItemGroup>
先全局移除MaciOS文件夹的编译项,再针对目标平台主动包含,逻辑更清晰,避免条件判断冲突。
2. 让IDE识别自定义平台文件夹
添加配置告诉Visual Studio,MaciOS文件夹属于iOS和Mac Catalyst平台,解决智能提示和杂项文件标记问题:
<!-- 关联MaciOS文件夹到iOS和Mac Catalyst平台 --> <ItemGroup> <Folder Include="MaciOS\" /> <MauiPlatformFolder Include="MaciOS\" Platforms="ios;maccatalyst" /> </ItemGroup>
3. 确保Partial类一致性
检查MaciOS文件夹中的partial类,必须与共享上下文的类完全同名、同命名空间,示例如下:
共享代码定义:
namespace YourAppNamespace { public partial class PlatformInitializer { public partial void Initialize(); } }
MaciOS中的实现:
namespace YourAppNamespace { public partial class PlatformInitializer { public partial void Initialize() { // iOS和Mac Catalyst共享的初始化逻辑 } } }
4. 清理并重新生成项目
- 右键项目 → 清理
- 右键项目 → 重新生成
- 关闭并重新打开Visual Studio,确保配置生效
内容的提问来源于stack exchange,提问作者just_a_developer
相关产品推荐
相关产品推荐

