Nota
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Probablemente haya oído el lema de "One .NET": una única plataforma unificada para compilar cualquier tipo de aplicación. El SDK de .NET incluye ASP.NET Core, Entity Framework Core, Windows Forms, WPF y ML.NET, y agregará compatibilidad con más plataformas a lo largo del tiempo. .NET 5+ se esfuerza por proporcionar una experiencia en la que no es necesario razonar sobre los diferentes tipos de .NET, pero no intenta abstraer completamente el sistema operativo subyacente (SO). Seguirás pudiendo llamar a API específicas de la plataforma, por ejemplo, P/Invokes y WinRT.
Pero el uso de API específicas de la plataforma en un componente significa que el código ya no funciona en todas las plataformas. Necesitamos una manera de detectar esto en tiempo de diseño para que los desarrolladores obtengan diagnósticos cuando usan accidentalmente API específicas de la plataforma. Para lograr este objetivo, .NET 5 introdujo el analizador de compatibilidad de plataforma y las API complementarias para ayudar a los desarrolladores a identificar y usar API específicas de la plataforma cuando corresponda.
Las API complementarias incluyen:
- SupportedOSPlatformAttribute para anotar las API como específicas de la plataforma y UnsupportedOSPlatformAttribute anotar las API como no admitidas en un sistema operativo determinado. Estos atributos pueden incluir opcionalmente el número de versión y ya se han aplicado a algunas API específicas de la plataforma en las bibliotecas principales de .NET.
-
Is<Platform>()
yIs<Platform>VersionAtLeast(int major, int minor = 0, int build = 0, int revision = 0)
son métodos estáticos en la clase System.OperatingSystem para llamar de forma segura a APIs específicas de la plataforma. Por ejemplo, OperatingSystem.IsWindows() se puede usar para proteger una llamada a una API específica de Windows y OperatingSystem.IsWindowsVersionAtLeast() se puede usar para proteger una llamada API específica de Windows con versiones. Vea estos ejemplos de cómo se pueden usar estos métodos como protección de referencias de API específicas de la plataforma.
Prerrequisitos
El analizador de compatibilidad de la plataforma es uno de los analizadores de calidad de código de Roslyn. Estos analizadores se incluyen con el SDK de .NET. El analizador de compatibilidad de la plataforma solo está habilitado de forma predeterminada para proyectos que tienen como destino net5.0
o una versión posterior. Sin embargo, puede habilitarlo para proyectos que tienen como destino otras plataformas.
Cómo determina la dependencia de la plataforma el analizador
Se considera que una API sin atribución funciona en todas las plataformas de sistemas operativos.
Una API marcada con
[SupportedOSPlatform("platform")]
se considera solo portable a la plataforma especificada y cualquier plataforma de la que sea un subconjunto.- El atributo se puede aplicar varias veces para indicar compatibilidad con varias plataformas, por ejemplo
[SupportedOSPlatform("windows"), SupportedOSPlatform("Android29.0")]
. - Si la plataforma es un subconjunto de otra plataforma, el atributo implica que también se admite la plataforma superconjunto. Por ejemplo,
[SupportedOSPlatform("iOS")]
implica que la API se admite eniOS
y también en su plataforma de superconjunto,MacCatalyst
. - El analizador generará una advertencia si se hace referencia a las API específicas de la plataforma sin un contexto de plataforma adecuado:
-
Advierte si el proyecto no tiene como destino la plataforma admitida (por ejemplo, una API específica de Windows llamada desde un proyecto destinado a iOS
<TargetFramework>net5.0-ios14.0</TargetFramework>
). -
Advierte si el proyecto es multiplataforma y llama a APIs específicas de la plataforma (por ejemplo, una API específica de Windows llamada desde un TFM multiplataforma
<TargetFramework>net5.0</TargetFramework>
). -
No advierte si se hace referencia a la API específica de la plataforma dentro de un proyecto que tiene como destino cualquiera de las plataformas especificadas (por ejemplo, para una API específica de Windows llamada desde una ventana
<TargetFramework>net5.0-windows</TargetFramework>
de destino de un proyecto y la generación de archivos AssemblyInfo.cs está habilitada para el proyecto). -
No advierte si la llamada API específica de la plataforma está protegida por los métodos de comprobación de plataforma correspondientes (por ejemplo, una llamada API específica de Windows protegida por
OperatingSystem.IsWindows()
). -
No advierte si se hace referencia a la API específica de la plataforma desde el mismo contexto específico de la plataforma (el sitio de llamada también tiene un atributo con
[SupportedOSPlatform("platform")
).
-
Advierte si el proyecto no tiene como destino la plataforma admitida (por ejemplo, una API específica de Windows llamada desde un proyecto destinado a iOS
- El atributo se puede aplicar varias veces para indicar compatibilidad con varias plataformas, por ejemplo
Se considera que una API marcada con
[UnsupportedOSPlatform("platform")]
no es compatible en la plataforma especificada y en todas las plataformas de las que se trata de un subconjunto, pero se admite para todas las demás plataformas.- El atributo se puede aplicar varias veces con distintas plataformas, por ejemplo,
[UnsupportedOSPlatform("iOS"), UnsupportedOSPlatform("Android29.0")]
. - Si la plataforma es un subconjunto de otra plataforma, el atributo implica que la plataforma de superconjunto también no se admite. Por ejemplo,
[UnsupportedOSPlatform("iOS")]
implica que la API no se admite eniOS
y también en su plataforma de superconjunto,MacCatalyst
. - El analizador genera una advertencia solo si el
platform
es efectivo para el punto de llamada:Advierte si el proyecto tiene como destino la plataforma que se atribuye como no admitida (por ejemplo, si la API se atribuye a
[UnsupportedOSPlatform("windows")]
y el sitio de llamada tiene como destino<TargetFramework>net5.0-windows</TargetFramework>
).Advierte si el proyecto tiene varios destinos y
platform
se incluye en el grupo de elementos de MSBuild<SupportedPlatform>
predeterminado oplatform
se incluye manualmente en elMSBuild
<grupo de elementos SupportedPlatform> :<ItemGroup> <SupportedPlatform Include="platform" /> </ItemGroup>
No advierte si va a compilar una aplicación que no tenga como destino la plataforma no admitida o sea de destino múltiple y la plataforma no esté incluida en el grupo de elementos de MSBuild
<SupportedPlatform>
predeterminado.
- El atributo se puede aplicar varias veces con distintas plataformas, por ejemplo,
Se puede crear una instancia de ambos atributos con o sin números de versión como parte del nombre de la plataforma. Los números de versión están en el formato de
major.minor[.build[.revision]]
;major.minor
es necesario y lasbuild
partes yrevision
son opcionales. Por ejemplo, "Windows6.1" indica la versión 6.1 de Windows, pero "Windows" se interpreta como Windows 0.0.
Para obtener más información, vea ejemplos de cómo funcionan los atributos y qué diagnóstico provocan.
Cómo reconoce el analizador las plataformas de destino de TFM
El analizador no comprueba las plataformas de destino del moniker de la plataforma de destino (TFM) desde las propiedades de MSBuild, como <TargetFramework>
o <TargetFrameworks>
. Si el TFM tiene una plataforma de destino, MSBuild inserta un SupportedOSPlatform
atributo con el nombre de la plataforma de destino en el archivo AssemblyInfo.cs , que el analizador consume. Por ejemplo, si el TFM es net5.0-windows10.0.19041
, MSBuild inserta el [assembly: System.Runtime.Versioning.SupportedOSPlatform("windows10.0.19041")]
atributo en el archivo AssemblyInfo.cs y todo el ensamblado se considera solo Windows. Por tanto, la llamada a las API exclusivas de Windows con la versión 7.0 o inferior no provocaría ninguna advertencia en el proyecto.
Nota:
Si la generación del archivo AssemblyInfo.cs está deshabilitada para el proyecto (es decir, la propiedad <GenerateAssemblyInfo>
se establece en false
), MSBuild no puede agregar el atributo necesario de nivel de ensamblado SupportedOSPlatform
. En este caso, podría ver advertencias sobre el uso de API específicas de la plataforma, aunque tenga como destino esa plataforma. Para resolver las advertencias, habilite la generación de archivos AssemblyInfo.cs o agregue el atributo manualmente en el proyecto.
Inclusión de plataformas
.NET 6 introdujo el concepto de inclusión de la plataforma, donde una plataforma puede ser un subconjunto de otra plataforma. Una anotación para la plataforma de subconjunto implica la misma compatibilidad (o falta de ella) con la plataforma de superconjunto. Si un método de comprobación de plataforma en el OperatingSystem tipo tiene un SupportedOSPlatformGuard("supersetPlatform")]
atributo , supersetPlatform
se considera un superconjunto de la plataforma del sistema operativo que comprueba el método.
Por ejemplo, el OperatingSystem.IsIOS() método se atribuye a [SupportedOSPlatformGuard("MacCatalyst")]
. Por lo tanto, se aplican las siguientes declaraciones:
- Los OperatingSystem.IsIOS() métodos y OperatingSystem.IsIOSVersionAtLeast comprueban no solo la
iOS
plataforma, sino también laMacCatalyst
plataforma. -
[SupportedOSPlatform("iOS")]
implica que la API se admite eniOS
y también en su plataforma de superconjunto,MacCatalyst
. Puede usar el[UnsupportedOSPlatform("MacCatalyst")]
atributo para excluir esta compatibilidad implícita. -
[UnsupportedOSPlatform("iOS")
implica que la API no se admite eniOS
yMacCatalyst
. Puede usar el[SupportedOSPlatform("MacCatalyst")]
atributo para excluir esta falta implícita de compatibilidad.
Tenga en cuenta la siguiente matriz de cobertura, donde ✔️ indica que se admite la plataforma e ❌ indica que no se admite la plataforma.
Plataforma | SupportedOSPlatform(subset) |
SupportedOSPlatform(superset) |
UnsupportedOSPlatform(subset) |
UnsupportedOSPlatform(superset) |
---|---|---|---|---|
Subconjunto | ✔️ | ❌ | ✔️ | ❌ |
Superconjunto | ✔️ | ✔️ | ✔️ | ✔️ |
Sugerencia
Las mismas reglas se aplican a los SupportedOSPlatformGuard
atributos y UnsupportedOSPlatformGuard
.
El siguiente fragmento de código muestra cómo puede combinar atributos para establecer el nivel correcto de compatibilidad.
// MacCatalyst is a superset of iOS therefore supported on iOS and MacCatalyst
[SupportedOSPlatform("iOS")]
public void ApiOnlySupportedOnIOSAndMacCatalyst() { }
// Does not imply iOS, only supported on MacCatalyst
[SupportedOSPlatform("MacCatalyst")]
public void ApiOnlySupportedOnMacCatalyst() { }
[SupportedOSPlatform("iOS")] // Supported on iOS and MacCatalyst
[UnsupportedOSPlatform("MacCatalyst")] // Removes implied MacCatalyst support
public void ApiOnlySupportedOnIos() { }
// Unsupported on iOS and MacCatalyst
[UnsupportedOSPlatform("iOS")]
public void ApiUnsupportedOnIOSAndMacCatalyst();
// Does not imply iOS, only unsupported on MacCatalyst
[UnsupportedOSPlatform("MacCatalyst")]
public void ApiUnsupportedOnMacCatalyst() { }
[UnsupportedOSPlatform("iOS")] // Unsupported on iOS and MacCatalyst
[SupportedOSPlatform("MacCatalyst")] // Removes implied MacCatalyst unsupportedness
public void ApiUnsupportedOnIos() { }
Escenarios avanzados para combinaciones de atributos
Si hay una combinación de
[SupportedOSPlatform]
atributos y[UnsupportedOSPlatform]
, todos los atributos se agrupan por identificador de plataforma del sistema operativo:Lista Solo compatibles. Si la versión más antigua de cada plataforma de sistema operativo es un atributo
[SupportedOSPlatform]
, se considera que la API solo es compatible con las plataformas de la lista y no es compatible con todas las demás plataformas. Los atributos opcionales[UnsupportedOSPlatform]
de cada plataforma solo pueden tener una versión superior de la versión mínima admitida, lo que indica que la API se quita a partir de la versión especificada.// API is only supported on Windows from version 6.2 to 10.0.19041.0 and all versions of Linux // The API is considered not supported for all other platforms. [SupportedOSPlatform("windows6.2")] [UnsupportedOSPlatform("windows10.0.19041.0")] [SupportedOSPlatform("linux")] public void ApiSupportedFromWindows80SupportFromCertainVersion();
Lista Solo no compatibles Si la versión más antigua de cada plataforma de sistema operativo es un atributo
[UnsupportedOSPlatform]
, se considera que la API no es compatible solo con las plataformas de la lista y es compatible con todas las demás plataformas. La lista podría tener[SupportedOSPlatform]
un atributo con la misma plataforma, pero una versión superior, lo que indica que la API se admite a partir de esa versión.// The API is unsupported on all Linux versions was unsupported on Windows until version 10.0.19041.0. // The API is considered supported everywhere else without constraints. [UnsupportedOSPlatform("windows")] [SupportedOSPlatform("windows10.0.19041.0")] [UnsupportedOSPlatform("linux")] public void ApiSupportedFromWindows8UnsupportedFromWindows10();
Lista de incoherentes: Si la versión más baja para algunas plataformas es
[SupportedOSPlatform]
mientras se usa[UnsupportedOSPlatform]
para otras plataformas, se considera incoherente, que no es compatible con el analizador. Si se produce incoherencia, el analizador omite las[UnsupportedOSPlatform]
plataformas.- Si las versiones más bajas de los atributos
[SupportedOSPlatform]
y[UnsupportedOSPlatform]
son iguales, el analizador considera la plataforma como parte de la Lista de solo compatibles.
- Si las versiones más bajas de los atributos
Los atributos de plataforma se pueden aplicar a tipos, miembros (métodos, campos, propiedades y eventos) y ensamblados con diferentes nombres de plataforma o versiones.
- Los atributos aplicados en el nivel
target
superior afectan a todos sus miembros y tipos. - Los atributos de nivel secundario solo se aplican si cumplen la regla "las anotaciones secundarias pueden restringir la compatibilidad con las plataformas, pero no pueden ampliarla".
- Cuando el elemento primario tiene la lista Solo compatibles, los atributos de los miembros secundarios no pueden agregar una nueva compatibilidad con la plataforma, ya que eso extendería la compatibilidad con el elemento primario. La compatibilidad con una nueva plataforma solo se puede agregar al propio elemento primario. Pero el elemento secundario puede tener el atributo
Supported
para la misma plataforma con versiones posteriores, ya que eso limita la compatibilidad. Además, el elemento secundario puede tener el atributoUnsupported
con la misma plataforma, lo que también limita la compatibilidad con el elemento primario. - Cuando el elemento primario tiene la lista Solo no compatibles, los atributos de los miembros secundarios no pueden agregar compatibilidad con una plataforma nueva, ya que eso limitaría la compatibilidad con el elemento primario. Pero no puede tener el atributo
Supported
para la misma plataforma que el elemento primario, porque eso amplía la compatibilidad con el elemento primario. La compatibilidad con la misma plataforma solo se puede agregar al elemento primario donde se aplicó el atributo originalUnsupported
.
- Cuando el elemento primario tiene la lista Solo compatibles, los atributos de los miembros secundarios no pueden agregar una nueva compatibilidad con la plataforma, ya que eso extendería la compatibilidad con el elemento primario. La compatibilidad con una nueva plataforma solo se puede agregar al propio elemento primario. Pero el elemento secundario puede tener el atributo
- Si
[SupportedOSPlatform("platformVersion")]
se aplica más de una vez para una API con el mismoplatform
nombre, el analizador solo tiene en cuenta el que tiene la versión mínima. - Si
[UnsupportedOSPlatform("platformVersion")]
se aplica más de dos veces para una API con el mismoplatform
nombre, el analizador solo tiene en cuenta los dos con las versiones más antiguas.
Nota:
No se espera que una API que inicialmente era compatible, pero que dejó de serlo (se eliminó) en una versión posterior, vuelva a ser compatible en una versión aún más reciente.
- Los atributos aplicados en el nivel
Ejemplos de cómo funcionan los atributos y qué diagnóstico generan
// An API supported only on Windows all versions.
[SupportedOSPlatform("Windows")]
public void WindowsOnlyApi() { }
// an API supported on Windows and Linux.
[SupportedOSPlatform("Windows")]
[SupportedOSPlatform("Linux")]
public void SupportedOnWindowsAndLinuxOnly() { }
// an API only supported on Windows 6.2 and later, not supported for all other.
// an API is removed/unsupported from version 10.0.19041.0.
[SupportedOSPlatform("windows6.2")]
[UnsupportedOSPlatform("windows10.0.19041.0")]
public void ApiSupportedFromWindows8UnsupportedFromWindows10() { }
// an Assembly supported on Windows, the API added from version 10.0.19041.0.
[assembly: SupportedOSPlatform("Windows")]
[SupportedOSPlatform("windows10.0.19041.0")]
public void AssemblySupportedOnWindowsApiSupportedFromWindows10() { }
public void Caller()
{
WindowsOnlyApi(); // warns: This call site is reachable on all platforms. 'WindowsOnlyApi()' is only supported on: 'windows'
// This call site is reachable on all platforms. 'SupportedOnWindowsAndLinuxOnly()' is only supported on: 'Windows', 'Linux'
SupportedOnWindowsAndLinuxOnly();
// This call site is reachable on all platforms. 'ApiSupportedFromWindows8UnsupportedFromWindows10()' is only supported on: 'windows' from version 6.2 to 10.0.19041.0
ApiSupportedFromWindows8UnsupportedFromWindows10();
// for same platform analyzer only warn for the latest version.
// This call site is reachable on all platforms. 'AssemblySupportedOnWindowsApiSupportedFromWindows10()' is only supported on: 'windows' 10.0.19041.0 and later
AssemblySupportedOnWindowsApiSupportedFromWindows10();
}
// an API not supported on android but supported on all other.
[UnsupportedOSPlatform("android")]
public void DoesNotWorkOnAndroid() { }
// an API was unsupported on Windows until version 6.2.
// The API is considered supported everywhere else without constraints.
[UnsupportedOSPlatform("windows")]
[SupportedOSPlatform("windows6.2")]
public void StartedWindowsSupportFromVersion8() { }
// an API was unsupported on Windows until version 6.2.
// Then the API is removed (unsupported) from version 10.0.19041.0.
// The API is considered supported everywhere else without constraints.
[UnsupportedOSPlatform("windows")]
[SupportedOSPlatform("windows6.2")]
[UnsupportedOSPlatform("windows10.0.19041.0")]
public void StartedWindowsSupportFrom8UnsupportedFrom10() { }
public void Caller2()
{
DoesNotWorkOnAndroid(); // This call site is reachable on all platforms.'DoesNotWorkOnAndroid()' is unsupported on: 'android'
// This call site is reachable on all platforms. 'StartedWindowsSupportFromVersion8()' is unsupported on: 'windows' 6.2 and before.
StartedWindowsSupportFromVersion8();
// This call site is reachable on all platforms. 'StartedWindowsSupportFrom8UnsupportedFrom10()' is supported on: 'windows' from version 6.2 to 10.0.19041.0
StartedWindowsSupportFrom8UnsupportedFrom10();
}
Gestión de advertencias notificadas
La manera recomendada de tratar estos diagnósticos es asegurarse de que solo se llama a las API específicas de la plataforma cuando se ejecuta en una plataforma adecuada. A continuación se muestran las opciones que puede usar para abordar las advertencias; elija lo que sea más adecuado para su situación:
Proteja la llamada. Puede lograrlo llamando condicionalmente al código en tiempo de ejecución. Compruebe si se ejecuta en una
Platform
deseada mediante uno de los métodos de comprobación de plataforma, por ejemplo,OperatingSystem.Is<Platform>()
uOperatingSystem.Is<Platform>VersionAtLeast(int major, int minor = 0, int build = 0, int revision = 0)
. ejemplo.Marque el sitio de llamada como específico de la plataforma. También puede elegir marcar sus propias API como específicas de la plataforma y, por tanto, reenviar los requisitos a los autores de llamadas de forma eficaz. Marque el método o tipo contenedor o todo el ensamblado con los mismos atributos que la llamada dependiente de la plataforma a la que se hace referencia. Ejemplos.
Aserción del sitio de llamada con comprobación de la plataforma. Si no desea la sobrecarga de una instrucción adicional
if
en tiempo de ejecución, use Debug.Assert(Boolean). ejemplo.Elimine el código. Por lo general, no lo que desea porque significa que perderá fidelidad cuando los usuarios de Windows usen el código. En los casos en los que existe una alternativa multiplataforma, es probable que sea mejor usarla en lugar de las API específicas de la plataforma.
Suprima la advertencia. También puede suprimir la advertencia, ya sea a través de una entrada EditorConfig o
#pragma warning disable CA1416
. Sin embargo, esta opción debe ser un último recurso cuando se usan API específicas de la plataforma.Sugerencia
Al deshabilitar las advertencias mediante las directivas del precompilador
#pragma
, los identificadores de destino distinguen mayúsculas de minúsculas. Por ejemplo,ca1416
no deshabilitaría realmente la advertencia CA1416.
Restricción de API específicas de la plataforma con métodos de restricción
El nombre de la plataforma del método de restricción debe coincidir con el nombre de la plataforma de API dependiente de la plataforma que llama. Si la API que llama tiene una cadena de plataforma que incluye la versión:
En el caso del atributo
[SupportedOSPlatform("platformVersion")]
, laversion
de la plataforma del método de restricción debe ser mayor o igual que laVersion
de la plataforma que realiza la llamada.En el caso del atributo
[UnsupportedOSPlatform("platformVersion")]
, laversion
de la plataforma del método de restricción debe ser menor o igual que laVersion
de la plataforma que realiza la llamada.public void CallingSupportedOnlyApis() // Allow list calls { if (OperatingSystem.IsWindows()) { WindowsOnlyApi(); // will not warn } if (OperatingSystem.IsLinux()) { SupportedOnWindowsAndLinuxOnly(); // will not warn, within one of the supported context } // Can use &&, || logical operators to guard combined attributes if (OperatingSystem.IsWindowsVersionAtLeast(6, 2) && !OperatingSystem.IsWindowsVersionAtLeast(10, 0, 19041))) { ApiSupportedFromWindows8UnsupportedFromWindows10(); } if (OperatingSystem.IsWindowsVersionAtLeast(10, 0, 19041, 0)) { AssemblySupportedOnWindowsApiSupportedFromWindows10(); // Only need to check latest supported version } } public void CallingUnsupportedApis() { if (!OperatingSystem.IsAndroid()) { DoesNotWorkOnAndroid(); // will not warn } if (!OperatingSystem.IsWindows() || OperatingSystem.IsWindowsVersionAtLeast(6, 2)) { StartedWindowsSupportFromVersion8(); // will not warn } if (!OperatingSystem.IsWindows() || // supported all other platforms (OperatingSystem.IsWindowsVersionAtLeast(6, 2) && !OperatingSystem.IsWindowsVersionAtLeast(10, 0, 19041))) { StartedWindowsSupportFrom8UnsupportedFrom10(); // will not warn } }
Si necesita proteger el código que tiene como destino
netstandard
onetcoreapp
dónde no están disponibles las nuevas OperatingSystem API, el analizador puede usar la RuntimeInformation.IsOSPlatform API y respetarla. Pero no está tan optimizado como las nuevas API agregadas en OperatingSystem. Si la plataforma no se admite en la estructura OSPlatform, puede llamar a OSPlatform.Create(String) y pasar el nombre de la plataforma, que el analizador también respeta.public void CallingSupportedOnlyApis() { if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { SupportedOnWindowsAndLinuxOnly(); // will not warn } if (RuntimeInformation.IsOSPlatform(OSPlatform.Create("browser"))) { ApiOnlySupportedOnBrowser(); // call of browser specific API } }
Anotación de las API con atributos de protección de plataforma y su uso como protección personalizada
Como se ha mostrado anteriormente, el analizador reconoce los métodos estáticos de protección de plataforma en el OperatingSystem tipo , como OperatingSystem.IsWindows
, y también RuntimeInformation.IsOSPlatform. Sin embargo, es posible que quiera almacenar en caché el resultado de la protección en un campo y reutilizarlo o usar métodos de protección personalizados para comprobar una plataforma. El analizador debe reconocer estas API como una protección personalizada y no debe advertir a las API protegidas por ellas. Los atributos de protección se introdujeron en .NET 6 para admitir este escenario:
-
SupportedOSPlatformGuardAttribute
anota las API que se pueden usar como protección para las API anotadas con SupportedOSPlatformAttribute. -
UnsupportedOSPlatformGuardAttribute
anota las API que se pueden usar como protección para las API anotadas con UnsupportedOSPlatformAttribute.
Estos atributos pueden incluir opcionalmente un número de versión. Se pueden aplicar varias veces para proteger más de una plataforma y se pueden usar para anotar un campo, una propiedad o un método.
class Test
{
[UnsupportedOSPlatformGuard("browser")] // The platform guard attribute
#if TARGET_BROWSER
internal bool IsSupported => false;
#else
internal bool IsSupported => true;
#endif
[UnsupportedOSPlatform("browser")]
void ApiNotSupportedOnBrowser() { }
void M1()
{
ApiNotSupportedOnBrowser(); // Warns: This call site is reachable on all platforms.'ApiNotSupportedOnBrowser()' is unsupported on: 'browser'
if (IsSupported)
{
ApiNotSupportedOnBrowser(); // Not warn
}
}
[SupportedOSPlatform("Windows")]
[SupportedOSPlatform("Linux")]
void ApiOnlyWorkOnWindowsLinux() { }
[SupportedOSPlatformGuard("Linux")]
[SupportedOSPlatformGuard("Windows")]
private readonly bool _isWindowOrLinux = OperatingSystem.IsLinux() || OperatingSystem.IsWindows();
void M2()
{
ApiOnlyWorkOnWindowsLinux(); // This call site is reachable on all platforms.'ApiOnlyWorkOnWindowsLinux()' is only supported on: 'Linux', 'Windows'.
if (_isWindowOrLinux)
{
ApiOnlyWorkOnWindowsLinux(); // Not warn
}
}
}
Marcar el sitio de llamada como específico de la plataforma
Los nombres de plataforma deben coincidir con la API dependiente de la plataforma en la que se está invocando. Si la cadena de la plataforma incluye una versión:
Para el
[SupportedOSPlatform("platformVersion")]
atributo , la plataformaversion
del sitio de llamada debe ser mayor o igual que la de la plataforma que realiza la llamada.Version
En el caso del atributo
[UnsupportedOSPlatform("platformVersion")]
, laversion
de la plataforma del sitio de llamada debe ser menor o igual que laVersion
de la plataforma que realiza la llamada.// an API supported only on Windows. [SupportedOSPlatform("windows")] public void WindowsOnlyApi() { } // an API supported on Windows and Linux. [SupportedOSPlatform("Windows")] [SupportedOSPlatform("Linux")] public void SupportedOnWindowsAndLinuxOnly() { } // an API only supported on Windows 6.2 and later, not supported for all other. // an API is removed/unsupported from version 10.0.19041.0. [SupportedOSPlatform("windows6.2")] [UnsupportedOSPlatform("windows10.0.19041.0")] public void ApiSupportedFromWindows8UnsupportedFromWindows10() { } // an Assembly supported on Windows, the API added from version 10.0.19041.0. [assembly: SupportedOSPlatform("Windows")] [SupportedOSPlatform("windows10.0.19041.0")] public void AssemblySupportedOnWindowsApiSupportedFromWindows10() { } [SupportedOSPlatform("windows6.2")] // call site attributed Windows 6.2 or above. public void Caller() { WindowsOnlyApi(); // will not warn as call site is for Windows. // will not warn as call site is for Windows all versions. SupportedOnWindowsAndLinuxOnly(); // will not warn for the [SupportedOSPlatform("windows6.2")] attribute, but warns for [UnsupportedOSPlatform("windows10.0.19041.0")] // This call site is reachable on: 'windows' 6.2 and later. 'ApiSupportedFromWindows8UnsupportedFromWindows10()' is unsupported on: 'windows' 10.0.19041.0 and later. ApiSupportedFromWindows8UnsupportedFromWindows10(); // The call site version is lower than the calling version, so warns: // This call site is reachable on: 'windows' 6.2 and later. 'AssemblySupportedOnWindowsApiSupportedFromWindows10()' is only supported on: 'windows' 10.0.19041.0 and later AssemblySupportedOnWindowsApiSupportedFromWindows10(); } [SupportedOSPlatform("windows10.0.22000")] // call site attributed with windows 10.0.22000 or above. public void Caller2() { // This call site is reachable on: 'windows' 10.0.22000 and later. 'ApiSupportedFromWindows8UnsupportedFromWindows10()' is unsupported on: 'windows' 10.0.19041.0 and later. ApiSupportedFromWindows8UnsupportedFromWindows10(); // will not warn as call site version higher than calling API. AssemblySupportedOnWindowsApiSupportedFromWindows10(); } [SupportedOSPlatform("windows6.2")] [UnsupportedOSPlatform("windows10.0.19041.0")] // call site supports Windows from version 6.2 to 10.0.19041.0. public void Caller3() { // will not warn as caller has exact same attributes. ApiSupportedFromWindows8UnsupportedFromWindows10(); // The call site reachable for the version not supported in the calling API, therefore warns: // This call site is reachable on: 'windows' from version 6.2 to 10.0.19041.0. 'AssemblySupportedOnWindowsApiSupportedFromWindows10()' is only supported on: 'windows' 10.0.19041.0 and later. AssemblySupportedOnWindowsApiSupportedFromWindows10(); } // an API not supported on Android but supported on all other. [UnsupportedOSPlatform("android")] public void DoesNotWorkOnAndroid() { } // an API was unsupported on Windows until version 6.2. // The API is considered supported everywhere else without constraints. [UnsupportedOSPlatform("windows")] [SupportedOSPlatform("windows6.2")] public void StartedWindowsSupportFromVersion8() { } // an API was unsupported on Windows until version 6.2. // Then the API is removed (unsupported) from version 10.0.19041.0. // The API is considered supported everywhere else without constraints. [UnsupportedOSPlatform("windows")] [SupportedOSPlatform("windows6.2")] [UnsupportedOSPlatform("windows10.0.19041.0")] public void StartedWindowsSupportFrom8UnsupportedFrom10() { } [UnsupportedOSPlatform("windows")] // Caller no support Windows for any version. public void Caller4() { // This call site is reachable on all platforms.'DoesNotWorkOnAndroid()' is unsupported on: 'android' DoesNotWorkOnAndroid(); // will not warns as the call site not support Windows at all, but supports all other. StartedWindowsSupportFromVersion8(); // same, will not warns as the call site not support Windows at all, but supports all other. StartedWindowsSupportFrom8UnsupportedFrom10(); } [UnsupportedOSPlatform("windows")] [UnsupportedOSPlatform("android")] // Caller not support Windows and Android for any version. public void Caller4() { DoesNotWorkOnAndroid(); // will not warn as call site not supports Android. // will not warns as the call site not support Windows at all, but supports all other. StartedWindowsSupportFromVersion8(); // same, will not warns as the call site not support Windows at all, but supports all other. StartedWindowsSupportFrom8UnsupportedFrom10(); }
Aserción del sitio de llamada con comprobación de la plataforma
Todas las comprobaciones condicionales usadas en los ejemplos de protección de plataforma también se pueden usar como condición para Debug.Assert(Boolean).
// An API supported only on Linux.
[SupportedOSPlatform("linux")]
public void LinuxOnlyApi() { }
public void Caller()
{
Debug.Assert(OperatingSystem.IsLinux());
LinuxOnlyApi(); // will not warn
}