共用方式為


連結 .NET MAUI Mac Catalyst 應用程式

建置應用程式時,.NET 多平臺應用程式 UI (.NET MAUI) 可以使用稱為 ILLink 的連結器來減少應用程式的整體大小。 ILLink 藉由分析編譯程式所產生的中繼程式代碼來減少大小。 它會移除未使用的方法、屬性、欄位、事件、結構及類別,以產生只包含執行應用程式所需的程式代碼和元件相依性的應用程式。

鏈接器行為

鏈接器支援 iOS 和 Mac Catalyst 上 .NET MAUI 應用程式的三種模式:

  • 不要連結。 停用連結可確保不會修改元件。
  • 連結 SDK 元件。 在此模式中,連結器會讓元件保持不變,並藉由移除應用程式未使用的類型和成員來減少 SDK 元件的大小。
  • 連結所有元件。 當連結所有元件時,連結器會執行其他優化,讓您的應用程式盡可能小。 它會修改原始程式碼的中繼程式碼,如果您使用連結器靜態分析無法偵測到的方法,可能會中斷您的應用程式。 在這些情況下,您可能需要調整原始程式碼,讓您的應用程式正常運作。

您可以針對應用程式的每個組建組態設定連結器行為。

警告

啟用應用程式偵錯組態的連結器可能會妨礙偵錯體驗,因為它可能會移除屬性存取子,讓您檢查物件的狀態。

若要在 Visual Studio Code 中設定連結器行為,您應該將 $(MtouchLink) 組建屬性新增至應用程式 .csproj 檔案中的屬性群組。 此組建屬性應設定為 NoneSdkOnlyFull

<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Debug|net8.0-maccatalyst|AnyCPU'">
  <MtouchLink>SdkOnly</MtouchLink>
</PropertyGroup>

或者,您可以在建置和發佈應用程式時,透過 CLI 指定連結器行為。 如需詳細資訊,請參閱 發佈 .NET MAUI Mac Catalyst 應用程式

重要

$(MtouchLink)您可以針對應用程式的每個組建組態個別設定組建屬性。

保留程序代碼

當您使用修剪器時,有時會移除您可能以動態方式呼叫的程式代碼,甚至是間接呼叫的程序代碼。 您可以使用 屬性標註 DynamicDependency 成員,指示修剪器保留成員。 這個屬性可用來表示對成員的類型和子集或特定成員的相依性。

重要

BCL 中無法以靜態方式判斷的應用程式所使用的每個成員,都可能會遭到移除。

屬性 DynamicDependency 可以套用至建構函式、欄位和方法:

[DynamicDependency("Helper", "MyType", "MyAssembly")]
static void RunHelper()
{
    var helper = Assembly.Load("MyAssembly").GetType("MyType").GetMethod("Helper");
    helper.Invoke(null, null);
}

在此範例中 DynamicDependency ,可確保 方法 Helper 會保留。 如果沒有 屬性,如果其他位置未參考,修剪將會 HelperMyAssembly 或移除完全移除 MyAssembly

屬性會指定要透過 string 或 透過 DynamicallyAccessedMembers 屬性保留的成員。 型別和組件在屬性內容中是隱含的,或在屬性中指定 (透過 Type 或透過 string 指定型別和組件名稱)。

型別和成員字串會使用 C# 檔註釋識別碼字串格式的變化,而不需要成員前置詞。 成員字串不應包含宣告類型的名稱,而且可能會省略參數來保留指定名稱的所有成員。 下列範例顯示有效的用法:

[DynamicDependency("Method()")]
[DynamicDependency("Method(System,Boolean,System.String)")]
[DynamicDependency("MethodOnDifferentType()", typeof(ContainingType))]
[DynamicDependency("MemberName")]
[DynamicDependency("MemberOnUnreferencedAssembly", "ContainingType", "UnreferencedAssembly")]
[DynamicDependency("MemberName", "Namespace.ContainingType.NestedType", "Assembly")]
// generics
[DynamicDependency("GenericMethodName``1")]
[DynamicDependency("GenericMethod``2(``0,``1)")]
[DynamicDependency("MethodWithGenericParameterTypes(System.Collections.Generic.List{System.String})")]
[DynamicDependency("MethodOnGenericType(`0)", "GenericType`1", "UnreferencedAssembly")]
[DynamicDependency("MethodOnGenericType(`0)", typeof(GenericType<>))]

保留元件

您可以指定應該從修剪程式排除的元件,同時允許修剪其他元件。 當您無法輕易使用 DynamicDependency 屬性,或無法控制正在修剪的程式代碼時,此方法會很有用。

當它修剪所有元件時,您可以藉由在專案檔中設定 TrimmerRootAssembly MSBuild 專案,告訴修剪器略過元件:

<ItemGroup>
  <TrimmerRootAssembly Include="MyAssembly" />
</ItemGroup>

注意

設定 .dllTrimmerRootAssembly MSBuild 屬性時,不需要延伸模組。

如果修剪器略過元件,則會將其視為 rooted,這表示會保留它及其所有靜態瞭解的相依性。 您可以將更多 TrimmerRootAssembly MSBuild 屬性新增至 , <ItemGroup>以略過其他元件。

保留元件、類型和成員

您可以傳遞 XML 描述檔來指定需要保留哪些元件、類型和成員的修剪器。

若要在修剪所有元件時從修剪程式排除成員,請將項目檔中的 MSBuild 專案設定 TrimmerRootDescriptor 為定義要排除之成員的 XML 檔案:

<ItemGroup>
  <TrimmerRootDescriptor Include="MyRoots.xml" />
</ItemGroup>

XML 檔案接著會使用修剪器 描述元格式 來定義要排除的成員:

<linker>
  <assembly fullname="MyAssembly">
    <type fullname="MyAssembly.MyClass">
      <method name="DynamicallyAccessedMethod" />
    </type>
  </assembly>
</linker>

在此範例中,XML 檔案會指定應用程式動態存取的方法,該方法已排除在修剪之外。

當元件、類型或成員列在 XML 中時,預設動作會保留,這表示不論修剪器是否認為它是否使用,都會保留在輸出中。

注意

保留卷標模棱兩可。 如果您未提供下一層的詳細數據,則會包含所有子系。 如果未列出任何型別的元件,則會保留所有元件的類型和成員。

將元件標示為修剪安全

如果您的專案中有連結庫,或您是可重複使用連結庫的開發人員,而且您想要修剪器將元件視為可修剪,您可以將 MSBuild 屬性新增 IsTrimmable 至元件的項目檔,將元件標記為安全修剪:

<PropertyGroup>
    <IsTrimmable>true</IsTrimmable>
</PropertyGroup>

這會將您的元件標示為「可修剪」,並啟用該專案的修剪警告。 「可修剪」表示您的元件與修剪相容,且建置元件時不應有修剪警告。 在修剪的應用程式中使用時,元件未使用的成員會在最終輸出中移除。

在 .NET 9+ 中使用原生 AOT 部署時,將 IsAotCompatible MSBuild 屬性設定為 true 也會將 true 的值指派給 IsTrimmable 屬性,並啟用額外的 AOT 分析器組建屬性。 如需 AOT 分析器的詳細資訊,請參閱 AOT 相容性分析器。 如需 .NET MAUI 原生 AOT 部署的詳細資訊,請參閱 原生 AOT 部署

在項目檔中將 IsTrimmable MSBuild 屬性設定為 true ,會將 AssemblyMetadata 屬性插入元件中:

[assembly: AssemblyMetadata("IsTrimmable", "True")]

或者,您可以將 屬性新增 AssemblyMetadata 至元件,而不需要將 MSBuild 屬性新增 IsTrimmable 至元件的項目檔。

注意

IsTrimmable如果已為元件設定 MSBuild 屬性,這會覆寫 AssemblyMetadata("IsTrimmable", "True") 屬性。 這可讓您選擇元件進行修剪,即使元件沒有 屬性,或停用具有 屬性的元件修剪。

隱藏分析警告

啟用修剪器時,它會移除無法靜態存取的 IL。 使用反映或其他建立動態相依性模式的應用程式可能會因此中斷。 若要警告這類模式,將元件標示為修剪安全時,連結庫作者應將 SuppressTrimAnalysisWarnings MSBuild 屬性設定為 false

<PropertyGroup>
  <SuppressTrimAnalysisWarnings>false</SuppressTrimAnalysisWarnings>
</PropertyGroup>

不隱藏修剪分析警告將包含整個應用程式的警告,包括您自己的程式代碼、連結庫程式碼和 SDK 程式代碼。

顯示詳細的警告

修剪分析針對來自 PackageReference的每個元件最多會產生一個警告,指出元件的內部元件與修剪不相容。 身為連結庫作者,當您將元件標示為修剪安全時,應該藉由將 MSBuild 屬性TrimmerSingleWarn設定false為 來啟用所有元件的個別警告:

<PropertyGroup>
  <TrimmerSingleWarn>false</TrimmerSingleWarn>
</PropertyGroup>

此設定會顯示所有詳細的警告,而不是將它們折疊為每個元件的單一警告。