AppContext 類別

定義

提供成員,用於設定和擷取應用程式內容的相關資料。Provides members for setting and retrieving data about an application's context.

public ref class AppContext abstract sealed
public static class AppContext
type AppContext = class
Public Class AppContext
繼承
AppContext

備註

AppContext 類別可讓程式庫作者為使用者提供新功能的統一退出機制。The AppContext class enables library writers to provide a uniform opt-out mechanism for new functionality for their users. 它會建立元件之間的鬆散偶合合約,以便溝通退出要求。It establishes a loosely-coupled contract between components in order to communicate an opt-out request. 變更現有的功能時,此功能通常特別重要。This capability is typically important when a change is made to existing functionality. 相反地,已經有新功能的隱含選擇加入。Conversely, there is already an implicit opt-in for new functionality.

適用于程式庫開發人員的 AppCoNtextAppContext for library developers

程式庫會使用 AppContext 類別來定義和公開相容性參數,而程式庫使用者可以設定這些參數來影響程式庫行為。Libraries use the AppContext class to define and expose compatibility switches, while library users can set those switches to affect the library behavior. 根據預設,程式庫可提供新的功能,且它們只會在已設定此參數時變更它 (亦即,它們提供先前的功能)。By default, libraries provide the new functionality, and they only alter it (that is, they provide the previous functionality) if the switch is set. 這可讓程式庫提供現有 API 的新行為,同時繼續支援相依于先前行為的呼叫端。This allows libraries to provide new behavior for an existing API while continuing to support callers who depend on the previous behavior.

定義交換器名稱Defining the switch name

允許媒體櫃的取用者選擇不變更行為的最常見方式,是定義具名引數。The most common way to allow consumers of your library to opt out of a change of behavior is to define a named switch. value 的元素是名稱/值組,其中包含參數的名稱及其 Boolean 值。Its value element is a name/value pair that consists of the name of a switch and its Boolean value. 根據預設,參數一律會隱含地 false,以提供新的行為(並預設會加入宣告新的行為)。By default, the switch is always implicitly false, which provides the new behavior (and makes the new behavior opt-in by default). 將參數設定為 true 會啟用它,這會提供舊版的行為。Setting the switch to true enables it, which provides the legacy behavior. 將參數明確設定為 false 也會提供新的行為。Explicitly setting the switch to false also provides the new behavior.

針對交換器名稱使用一致的格式很有用,因為它們是程式庫所公開的正式合約。It's beneficial to use a consistent format for switch names, since they are a formal contract exposed by a library. 以下是兩種明顯的格式。The following are two obvious formats.

  • 參數.命名空間.參數名稱Switch.namespace.switchname

  • 參數.程式庫.參數名稱Switch.library.switchname

當您定義並記載參數之後,呼叫端就可以使用登錄來使用它,方法是將<AppCoNtextSwitchOverrides >專案新增至其應用程式佈建檔,或以程式設計方式呼叫 AppContext.SetSwitch(String, Boolean) 方法。Once you define and document the switch, callers can use it by using the registry, by adding an <AppContextSwitchOverrides> element to their application configuration file, or by calling the AppContext.SetSwitch(String, Boolean) method programmatically. 如需有關呼叫端如何使用的詳細資訊,以及如何設定 AppContext 配置參數的值,請參閱AppCoNtext for library 取用者一節。See the AppContext for library consumers section for more information about how callers use and set the value of AppContext configuration switches.

當 common language runtime 執行應用程式時,它會自動讀取登錄的相容性設定並載入應用程式佈建檔,以便填入應用程式的 AppContext 實例。When the common language runtime runs an application, it automatically reads the registry's compatibility settings and loads the application configuration file in order to populate the application's AppContext instance. 因為 AppContext 實例是由呼叫端或執行時間以程式設計方式填入,所以您不需要採取任何動作(例如呼叫 SetSwitch 方法)來設定 AppContext 實例。Because the AppContext instance is populated either programmatically by the caller or by the runtime, you do not have to take any action, such as calling the SetSwitch method, to configure the AppContext instance.

檢查設定Checking the setting

接著,您可以藉由呼叫 AppContext.TryGetSwitch 方法,檢查取用者是否已宣告參數的值,並適當地採取動作。You can then check if a consumer has declared the value of the switch and act appropriately by calling the AppContext.TryGetSwitch method. 如果找到 switchName 引數,方法會傳回 true,而當方法傳回時,其 isEnabled 引數會指出參數的值。The method returns true if the switchName argument is found, and when the method returns, its isEnabled argument indicates the value of the switch. 否則,方法會傳回 falseOtherwise, the method returns false.

範例An example

下列範例說明如何使用 AppContext 類別,讓客戶選擇程式庫方法的原始行為。The following example illustrates the use of the AppContext class to allow the customer to choose the original behavior of a library method. 以下是名為 StringLibrary之程式庫的1.0 版。The following is version 1.0 of a library named StringLibrary. 它會定義一個 SubstringStartsAt 方法,以執行序數比較,以判斷子字串在較大字串中的起始索引。It defines a SubstringStartsAt method that performs an ordinal comparison to determine the starting index of a substring within a larger string.

using System;
using System.Reflection;

[assembly: AssemblyVersion("1.0.0.0")]

public static class StringLibrary
{
   public static int SubstringStartsAt(String fullString, String substr)
   {
      return 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

接著,下列範例會使用程式庫,在 "the archaeologist" 中尋找子字串 "archæ" 的起始索引。The following example then uses the library to find the starting index of the substring "archæ" in "The archaeologist". 因為方法會執行序數比較,所以找不到子字串。Because the method performs an ordinal comparison, the substring cannot be found.

using System;

public class Example
{
   public static void Main()
   {
      String value = "The archaeologist";
      String substring = "archæ";
      int position = StringLibrary.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'
Public Module Example
   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版的程式庫會將 SubstringStartsAt 方法變更為使用區分文化特性的比較。Version 2 of the library, however, changes the SubstringStartsAt method to use culture-sensitive comparison.

using System;
using System.Reflection;

[assembly: AssemblyVersion("2.0.0.0")]

public static class StringLibrary
{
   public static int SubstringStartsAt(String fullString, String substr)
   {
      return 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

重新編譯應用程式以針對新版本的程式庫執行時,它現在會報告在 "the archaeologist" 的索引4中找到子字串 "archæ"。When the app is recompiled to run against the new version of the library, it now reports that the substring "archæ" is found at index 4 in "The archaeologist".

using System;

public class Example
{
   public static void Main()
   {
      String value = "The archaeologist";
      String substring = "archæ";
      int position = StringLibrary.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
Public Module Example
   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

這項變更可以藉由定義<AppCoNtextSwitchOverrides >參數,防止中斷相依于原始行為的應用程式。This change can be prevented from breaking the applications that depend on the original behavior by defining an <AppContextSwitchOverrides> switch. 在此情況下,參數的名稱為 StringLibrary.DoNotUseCultureSensitiveComparisonIn this case, the switch is named StringLibrary.DoNotUseCultureSensitiveComparison. 其預設值 false,表示程式庫應執行其2.0 版區分文化特性的比較。Its default value, false, indicates that the library should perform its version 2.0 culture-sensitive comparison. true 指出程式庫應執行其1.0 版序數比較。true indicates that the library should perform its version 1.0 ordinal comparison. 稍加修改先前的程式碼,可讓程式庫取用者設定參數,以決定方法所執行的比較類型。A slight modification of the previous code allows the library consumer to set the switch to determine the kind of comparison the method performs.

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);
   }
}
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

如果應用程式可以使用下列設定檔來還原1.0 版的行為。If application can then use the following configuration file to restore the version 1.0 behavior.

<configuration>
   <runtime>
      <AppContextSwitchOverrides value="StringLibrary.DoNotUseCultureSensitiveComparison=true" />
   </runtime>
</configuration>

當應用程式是以存在的設定檔執行時,它會產生下列輸出:When the application is run with the configuration file present, it produces the following output:

'archæ' not found in 'The archaeologist'

適用于程式庫取用者的 AppCoNtextAppContext for library consumers

如果您是程式庫的取用者,AppContext 類別可讓您利用程式庫或程式庫方法的退出機制來提供新功能。If you are the consumer of a library, the AppContext class allows you to take advantage of a library or library method's opt-out mechanism for new functionality. 您所呼叫之類別庫的個別方法會定義啟用或停用新行為的特定參數。Individual methods of the class library that you are calling define particular switches that enable or disable a new behavior. 參數的值是布林值。The value of the switch is a Boolean. 如果 false(通常是預設值),則會啟用新的行為。如果 true,則會停用新的行為,且成員的行為與先前相同。If it is false, which is typically the default value, the new behavior is enabled; if it is true, the new behavior is disabled, and the member behaves as it did previously.

您可以使用下列四種方式之一來設定參數的值:You can set the value of a switch in one of four ways:

  • 藉由在程式碼中呼叫 AppContext.SetSwitch(String, Boolean) 方法。By calling the AppContext.SetSwitch(String, Boolean) method in your code. switchName 引數會定義參數名稱,而 isEnabled 屬性會定義參數的值。The switchName argument defines the switch name, and the isEnabled property defines the value of the switch. 因為 AppContext 是靜態類別,所以可依每個應用程式網域來使用。Because AppContext is a static class, it is available on a per-application domain basis.

    呼叫 AppContext.SetSwitch(String, Boolean) 具有應用程式範圍;也就是說,它只會影響應用程式。Calling the AppContext.SetSwitch(String, Boolean) has application scope; that is, it affects only the application.

  • 藉由將 <AppContextSwitchOverrides> 元素新增至 app.config 檔案的<runtime >區段。By adding an <AppContextSwitchOverrides> element to the <runtime> section of your app.config file. 參數具有單一屬性,value,其值為字串,代表同時包含參數名稱和其值的索引鍵/值組。The switch has a single attribute, value, whose value is a string that represents a key/value pair containing both the switch name and its value.

    若要定義多個參數,請以分號分隔<AppCoNtextSwitchOverrides中的每個參數的索引鍵/值組 > 元素的 value 屬性。To define multiple switches, separate each switch's key/value pair in the <AppContextSwitchOverrides> element's value attribute with a semicolon. 在此情況下,<AppContextSwitchOverrides> 元素具有下列格式:In that case, the <AppContextSwitchOverrides> element has the following format:

    <AppContextSwitchOverrides value="switchName1=value1;switchName2=value2" />
    

    使用 <AppContextSwitchOverrides> 元素定義具有應用程式範圍的設定:也就是說,它只會影響應用程式。Using the <AppContextSwitchOverrides> element to define a configuration setting has application scope; that is, it affects only the application.

    注意

    如需 .NET Framework 所定義之參數的詳細資訊,請參閱<AppCoNtextSwitchOverrides > 元素For information on the switches defined by the .NET Framework, see the <AppContextSwitchOverrides> element.

  • 藉由新增字串值,其名稱為登錄中的 HKLM\SOFTWARE\Microsoft\.NETFramework\AppContext 機碼之參數的名稱。By adding a string value whose name is the name of the switch to the HKLM\SOFTWARE\Microsoft\.NETFramework\AppContext key in the registry. 其值必須是可由 Boolean.Parse 方法剖析之 Boolean 的字串標記法;也就是說,它必須是 "True"、"true"、"False" 或 "false"。Its value must be the string representation of a Boolean that can be parsed by the Boolean.Parse method; that is, it must be "True", "true", "False", or "false". 如果執行時間遇到任何其他值,則會忽略參數。If the runtime encounters any other value, it ignores the switch.

    使用登錄來定義 AppContext 交換器具有電腦範圍;也就是說,它會影響在機器上執行的每個應用程式。Using the registry to define an AppContext switch has machine scope; that is, it affects every application running on the machine.

  • 針對 ASP.NET 應用程式,您可以將<新增 >元素新增至 web.config 檔案的<appSettings >區段。For ASP.NET applications, you add an <Add> element to the <appSettings> section of the web.config file. 例如:For example:

    <appSettings>
        <add key="AppContext.SetSwitch:switchName1" value="switchValue1" />
        <add key="AppContext.SetSwitch:switchName2" value="switchValue2" />
    </appSettings>
    

如果您以一種以上的方式設定相同的交換器,判斷哪個設定會覆寫其他設定的優先順序順序為:If you set the same switch in more than one way, the order of precedence for determining which setting overrides the others is:

  1. 程式設計設定。The programmatic setting.

  2. 應用程式佈建檔或 web.config 檔案中的設定。The setting in the app config file or the web.config file.

  3. 登錄設定。The registry setting.

以下是簡單的應用程式,它會將檔案 URI 傳遞給 Path.GetDirectoryName 方法。The following is a simple application that passes a file URI to the Path.GetDirectoryName method. 在 .NET Framework 4.6 下執行時,它會擲回 ArgumentException,因為 file:// 不再是檔案路徑的有效部分。When run under the .NET Framework 4.6, it throws an ArgumentException because file:// is no longer a valid part of a file path.

using System;
using System.IO;
using System.Runtime.Versioning;

[assembly:TargetFramework(".NETFramework,Version=v4.6.2")]

public class Example
{
   public static void Main()
   {
      Console.WriteLine(Path.GetDirectoryName("file://c/temp/dirlist.txt"));
   }
}
// The example displays the following output:
//    Unhandled Exception: System.ArgumentException: The path is not of a legal form.
//       at System.IO.Path.NewNormalizePathLimitedChecks(String path, Int32 maxPathLength, Boolean expandShortPaths)
//       at System.IO.Path.NormalizePath(String path, Boolean fullCheck, Int32 maxPathLength, Boolean expandShortPaths)
//       at System.IO.Path.InternalGetDirectoryName(String path)
//       at Example.Main()
Imports System.IO
Imports System.Runtime.Versioning

<assembly:TargetFramework(".NETFramework,Version=v4.6.2")>

Module Example
   Public Sub Main()
      Console.WriteLine(Path.GetDirectoryName("file://c/temp/dirlist.txt")) 
   End Sub
End Module
' The example displays the following output:
'    Unhandled Exception: System.ArgumentException: The path is not of a legal form.
'       at System.IO.Path.NewNormalizePathLimitedChecks(String path, Int32 maxPathLength, Boolean expandShortPaths)
'       at System.IO.Path.NormalizePath(String path, Boolean fullCheck, Int32 maxPathLength, Boolean expandShortPaths)
'       at System.IO.Path.InternalGetDirectoryName(String path)
'       at Example.Main()

若要還原方法先前的行為並避免例外狀況,您可以將 Switch.System.IO.UseLegacyPathHandling 參數新增至範例的應用程式佈建檔:To restore the method's previous behavior and prevent the exception, you can add the Switch.System.IO.UseLegacyPathHandling switch to the application configuration file for the example:

<configuration>
    <runtime>
        <AppContextSwitchOverrides value="Switch.System.IO.UseLegacyPathHandling=true" />
    </runtime>
</configuration>

另請參閱See also

AppCoNtext 參數AppContext switch

屬性

BaseDirectory

取得組件解析程式用來探查組件之基底目錄的路徑名稱。Gets the pathname of the base directory that the assembly resolver uses to probe for assemblies.

TargetFrameworkName

取得目前應用程式設為目標的 Framework 版本名稱。Gets the name of the framework version targeted by the current application.

方法

GetData(String)

傳回指派給目前應用程式定義域的具名資料元素值。Returns the value of the named data element assigned to the current application domain.

SetSwitch(String, Boolean)

設定參數的值。Sets the value of a switch.

TryGetSwitch(String, Boolean)

嘗試取得參數的值。Tries to get the value of a switch.

適用於

另請參閱