System.AppContext 類別
本文提供此 API 參考文件的補充備註。
類別可讓連結 AppContext 庫寫入器為使用者的新功能提供統一的退出機制。 其會建立元件之間的鬆散結合合約,以便溝通退出要求。 變更現有的功能時,此功能通常特別重要。 相反地,已經有新功能的隱含選擇加入。
適用於連結庫開發人員的 AppContext
連結庫會使用 類別 AppContext 來定義和公開相容性參數,而連結庫用戶可以設定這些參數來影響連結庫行為。 根據預設,程式庫可提供新的功能,且它們只會在已設定此參數時變更它 (亦即,它們提供先前的功能)。 這可讓連結庫為現有的 API 提供新的行為,同時繼續支援相依於先前行為的呼叫端。
定義參數名稱
允許連結庫取用者退出退出行為變更的最常見方式是定義具名參數。 其 value
元素是名稱/值組,其中包含參數的名稱及其 Boolean 值。 根據預設,參數一律是隱含 false
的 ,這會提供新的行為(並預設會讓新的行為加入)。 將 參數設定為 true
可啟用它,以提供舊版行為。 明確將 參數設定為 false
也提供新的行為。
最好使用一致的參數名稱格式,因為它們是由連結庫公開的正式合約。 以下是兩種明顯的格式:
- 參數.命名空間.參數名稱
- 參數.程式庫.參數名稱
定義並記錄參數之後,呼叫端就可以透過程序設計方式呼叫 AppContext.SetSwitch(String, Boolean) 方法來使用它。 .NET Framework 應用程式也可以藉由將AppContextSwitchOverrides> 元素新增<至其應用程式組態檔或使用登錄,來使用 參數。 如需呼叫端如何使用和設定組態參數值 AppContext 的詳細資訊,請參閱 連結庫取用者的 AppContext 一節。
在 .NET Framework 中,當 Common Language Runtime 執行應用程式時,它會自動讀取登錄的相容性設定,並載入應用程式組態檔以填入應用程式的 AppContext 實例。 AppContext因為實例是以程序設計方式由呼叫端或運行時間填入,因此 .NET Framework 應用程式不需要採取任何動作,例如呼叫 SetSwitch 方法,來設定AppContext實例。
檢查設定
您可以檢查取用者是否已宣告參數的值,並藉由呼叫 AppContext.TryGetSwitch 方法來適當地採取行動。 如果switchName
找到自變數,則方法會true
傳回 ,而其isEnabled
自變數表示參數的值。 否則,方法會傳回 false
。
範例
下列範例說明 如何使用 AppContext 類別,讓客戶選擇連結庫方法的原始行為。 以下是名為 StringLibrary
的連結庫 1.0 版。 它會定義 SubstringStartsAt
方法,這個方法會執行序數比較,以判斷較大字串內子字串的起始索引。
using System;
using System.Reflection;
[assembly: AssemblyVersion("1.0.0.0")]
public static class StringLibrary1
{
public static int SubstringStartsAt(string fullString, string substr)
{
return fullString.IndexOf(substr, StringComparison.Ordinal);
}
}
open System
open System.Reflection
[<assembly: AssemblyVersion("1.0.0.0")>]
do ()
module StringLibrary =
let substringStartsAt (fullString: string) (substr: string) =
fullString.IndexOf(substr, StringComparison.Ordinal)
Imports System.Reflection
<Assembly: AssemblyVersion("1.0.0.0")>
Public Class StringLibrary
Public Shared Function SubstringStartsAt(fullString As String, substr As String) As Integer
Return fullString.IndexOf(substr, StringComparison.Ordinal)
End Function
End Class
下列範例接著會使用連結庫來尋找「考古學家」中子字串 「archæ」 的起始索引。 因為方法會執行序數比較,所以找不到子字串。
using System;
public class Example1
{
public static void Main()
{
string value = "The archaeologist";
string substring = "archæ";
int position = StringLibrary1.SubstringStartsAt(value, substring);
if (position >= 0)
Console.WriteLine("'{0}' found in '{1}' starting at position {2}",
substring, value, position);
else
Console.WriteLine("'{0}' not found in '{1}'", substring, value);
}
}
// The example displays the following output:
// 'archæ' not found in 'The archaeologist'
let value = "The archaeologist"
let substring = "archæ"
let position =
StringLibrary.substringStartsAt value substring
if position >= 0 then
printfn $"'{substring}' found in '{value}' starting at position {position}"
else
printfn $"'{substring}' not found in '{value}'"
// The example displays the following output:
// 'archæ' not found in 'The archaeologist'
Public Module Example4
Public Sub Main()
Dim value As String = "The archaeologist"
Dim substring As String = "archæ"
Dim position As Integer = StringLibrary.SubstringStartsAt(value, substring)
If position >= 0 Then
Console.WriteLine("'{0}' found in '{1}' starting at position {2}",
substring, value, position)
Else
Console.WriteLine("'{0}' not found in '{1}'", substring, value)
End If
End Sub
End Module
' The example displays the following output:
' 'archæ' not found in 'The archaeologist'
不過,連結庫 2.0 版會 SubstringStartsAt
變更 方法,以使用區分文化特性的比較。
using System;
using System.Reflection;
[assembly: AssemblyVersion("2.0.0.0")]
public static class StringLibrary2
{
public static int SubstringStartsAt(string fullString, string substr)
{
return fullString.IndexOf(substr, StringComparison.CurrentCulture);
}
}
open System
open System.Reflection
[<assembly: AssemblyVersion("2.0.0.0")>]
do ()
module StringLibrary =
let substringStartsAt (fullString: string) (substr: string) =
fullString.IndexOf(substr, StringComparison.CurrentCulture)
Imports System.Reflection
<Assembly: AssemblyVersion("2.0.0.0")>
Public Class StringLibrary
Public Shared Function SubstringStartsAt(fullString As String, substr As String) As Integer
Return fullString.IndexOf(substr, StringComparison.CurrentCulture)
End Function
End Class
當應用程式重新編譯以針對新版本的連結庫執行時,它現在報告在「考古學家」索引 4 中發現了子字串 「archæ」。。
using System;
public class Example2
{
public static void Main()
{
string value = "The archaeologist";
string substring = "archæ";
int position = StringLibrary2.SubstringStartsAt(value, substring);
if (position >= 0)
Console.WriteLine("'{0}' found in '{1}' starting at position {2}",
substring, value, position);
else
Console.WriteLine("'{0}' not found in '{1}'", substring, value);
}
}
// The example displays the following output:
// 'archæ' found in 'The archaeologist' starting at position 4
let value = "The archaeologist"
let substring = "archæ"
let position =
StringLibrary.substringStartsAt value substring
if position >= 0 then
printfn $"'{substring}' found in '{value}' starting at position {position}"
else
printfn $"'{substring}' not found in '{value}'"
// The example displays the following output:
// 'archæ' found in 'The archaeologist' starting at position 4
Public Module Example6
Public Sub Main()
Dim value As String = "The archaeologist"
Dim substring As String = "archæ"
Dim position As Integer = StringLibrary.SubstringStartsAt(value, substring)
If position >= 0 Then
Console.WriteLine("'{0}' found in '{1}' starting at position {2}",
substring, value, position)
Else
Console.WriteLine("'{0}' not found in '{1}'", substring, value)
End If
End Sub
End Module
' The example displays the following output:
' 'archæ' found in 'The archaeologist' starting at position 4
您可以藉由定義參數,防止中斷相依於原始行為的應用程式。 在這裡情況下,參數會命名為 StringLibrary.DoNotUseCultureSensitiveComparison
。 其預設值 false
表示連結庫應該執行其 2.0 版區分文化特性的比較。 true
表示連結庫應該執行其 1.0 版序數比較。 先前程序代碼的稍微修改可讓連結庫取用者設定 參數,以判斷方法執行的比較種類。
using System;
using System.Reflection;
[assembly: AssemblyVersion("2.0.0.0")]
public static class StringLibrary
{
public static int SubstringStartsAt(string fullString, string substr)
{
bool flag;
if (AppContext.TryGetSwitch("StringLibrary.DoNotUseCultureSensitiveComparison", out flag) && flag == true)
return fullString.IndexOf(substr, StringComparison.Ordinal);
else
return fullString.IndexOf(substr, StringComparison.CurrentCulture);
}
}
open System
open System.Reflection
[<assembly: AssemblyVersion("2.0.0.0")>]
do ()
AppContext.SetSwitch("StringLibrary.DoNotUseCultureSensitiveComparison",true)
module StringLibrary =
let substringStartsAt (fullString: string) (substr: string) =
match AppContext.TryGetSwitch "StringLibrary.DoNotUseCultureSensitiveComparison" with
| true, true -> fullString.IndexOf(substr, StringComparison.Ordinal)
| _ -> fullString.IndexOf(substr, StringComparison.CurrentCulture)
Imports System.Reflection
<Assembly: AssemblyVersion("2.0.0.0")>
Public Class StringLibrary
Public Shared Function SubstringStartsAt(fullString As String, substr As String) As Integer
Dim flag As Boolean
If AppContext.TryGetSwitch("StringLibrary.DoNotUseCultureSensitiveComparison", flag) AndAlso flag = True Then
Return fullString.IndexOf(substr, StringComparison.Ordinal)
Else
Return fullString.IndexOf(substr, StringComparison.CurrentCulture)
End If
End Function
End Class
然後,.NET Framework 應用程式可以使用下列組態檔來還原 1.0 版的行為。
<configuration>
<runtime>
<AppContextSwitchOverrides value="StringLibrary.DoNotUseCultureSensitiveComparison=true" />
</runtime>
</configuration>
當應用程式與組態檔一起執行時,會產生下列輸出:
'archæ' not found in 'The archaeologist'
連結庫取用者的 AppContext
如果您是連結庫的取用者,類別 AppContext 可讓您利用連結庫或連結庫方法的退出機制來取得新功能。 您呼叫之類別庫的個別方法會定義啟用或停用新行為的特定參數。 參數的值是布爾值。 false
如果是,這通常是預設值,則會啟用新行為;如果是 true
,則會停用新行為,而成員的行為就像先前所做的一樣。
您可以在程式代碼中呼叫 AppContext.SetSwitch(String, Boolean) 方法,以設定參數的值。 自 switchName
變數會定義參數名稱,而 isEnabled
屬性會定義參數的值。 因為 AppContext 是靜態類別,所以會根據每個應用程式域提供。 AppContext.SetSwitch(String, Boolean)呼叫 具有應用程式範圍;也就是說,它只會影響應用程式。
.NET Framework 應用程式有其他方法來設定參數的值:
將專案新增
<AppContextSwitchOverrides>
至 <app.config 檔案的運行時間> 區段。 參數具有單一屬性 ,其值為字串,value
表示包含參數名稱和其值的索引鍵/值組。若要定義多個參數,請使用分號分隔 AppContextSwitchOverrides> 元素
value
屬性中的每個<參數索引鍵/值組。 在此情況下,元素<AppContextSwitchOverrides>
的格式如下:<AppContextSwitchOverrides value="switchName1=value1;switchName2=value2" />
<AppContextSwitchOverrides>
使用 元素來定義組態設定具有應用程式範圍;也就是說,它只會影響應用程式。注意
如需 .NET Framework 所定義之參數的資訊,請參閱 <AppContextSwitchOverrides> 元素。
將專案新增至登錄。 將新的字串值新增至 HKLM\SOFTWARE\Microsoft\。NETFramework\AppContext 子機碼。 將項目的名稱設定為 參數的名稱。 將設定為下列其中一個選項:
True
、true
、False
或false
。 如果運行時間遇到任何其他值,則會忽略 參數。在 64 位作業系統上,您也必須將相同的專案新增至 HKLM\SOFTWARE\Wow6432Node\Microsoft\。NETFramework\AppContext 子機碼。
使用登錄來定義 AppContext 交換器具有計算機範圍;也就是說,它會影響計算機上執行的每個應用程式。
針對 ASP.NET 和 ASP.NET Core 應用程式,您可以將 Add> 元素新增<至< web.config 檔案的 app 設定> 區段來設定參數。 例如:
<appSettings>
<add key="AppContext.SetSwitch:switchName1" value="switchValue1" />
<add key="AppContext.SetSwitch:switchName2" value="switchValue2" />
</appSettings>
如果您以一種以上的方式設定相同的參數,判斷哪些設定會覆寫其他設定的優先順序為:
- 程序設計設定。
- app.config 檔案中的設定(適用於 .NET Framework 應用程式)或 web.config 檔案(適用於 ASP.NET Core 應用程式)。
- 登錄設定 (僅適用於 .NET Framework 應用程式)。