Skip to content

Unify MinimumOSPlatformAttribute and UnsupportedOSPlatformAttribute #39989

@terrajobst

Description

@terrajobst

The original proposal for marking-platform-specific APIs only considered cases where an API was platform-specific, such as the Windows registry. When trying to design a solution for marking APIs as unsupported by Blazor, it became obvious that we need a way to exclude some platforms without treating the API as platform-specific. Hence, a proposal for platform-exclusion was born dotnet/designs#143.

During the design, it emerged that it would be desirable to align these two proposals.

API proposal

  • Rename MinimumOSPlatformAttribute to SupportedOSPlatformAttribute
  • Rename RemovedInOSPlatformAttribute to UnsupportedOSPlatformAttribute
namespace System.Runtime.Versioning
{
    [AttributeUsage(AttributeTargets.Assembly |
                    AttributeTargets.Class |
                    AttributeTargets.Constructor |
                    AttributeTargets.Enum |
                    AttributeTargets.Event |
                    AttributeTargets.Field |
                    AttributeTargets.Method |
                    AttributeTargets.Module |
                    AttributeTargets.Property |
                    AttributeTargets.Struct,
                    AllowMultiple = true, Inherited = false)]
    public sealed class SupportedOSPlatformAttribute : OSPlatformAttribute
    {
        public SupportedOSPlatformAttribute(string platformName);
    }
  
    [AttributeUsage(AttributeTargets.Assembly |
                    AttributeTargets.Class |
                    AttributeTargets.Constructor |
                    AttributeTargets.Enum |
                    AttributeTargets.Event |
                    AttributeTargets.Field |
                    AttributeTargets.Method |
                    AttributeTargets.Module |
                    AttributeTargets.Property |
                    AttributeTargets.Struct,
                    AllowMultiple = true, Inherited = false)]
    public sealed class UnsupportedOSPlatformAttribute : OSPlatformAttribute
    {
        public UnsupportedOSPlatformAttribute(string platformName);
    }
}

The semantics of these new attributes are as follows:

  • An API that doesn't have any of these attributes is considered supported by all platforms.
  • If either [SupportedOSPlatform] or [UnsupportedOSPlatform] attributes are present, we group all attributes by OS platform identifier:
    • Allow list. If the lowest version for each OS platform is a [SupportedOSPlatform] attribute, the API is considered to only be supported by the listed platforms and unsupported by all other platforms.
    • Deny list. If the lowest version for each OS platform is a [UnsupportedOSPlatform] attribute, then the API is considered to only be unsupported by the listed platforms and supported by all other platforms.
    • Inconsistent list. If for some platforms the lowest version attribute is [SupportedOSPlatform] while for others it is [UnsupportedOSPlatform], the analyzer will produce a warning on the API definition because the API is attributed inconsistently.
  • Both attributes can be instantiated without version numbers. This means the version number is assumed to be 0.0. This simplifies guard clauses, see examples below for more details.
  • [ObsoletedInOSPlatform] continuous to require a version number.
  • [ObsoletedInOSPlatform] by itself doesn't imply support. However, it doesn't make sense to apply [ObsoletedInOSPlatform] unless that platform is supported.

API Usage

Unsuported platform

In .NET 5:

[UnsupportedOSPlatform("windows")]
public void DoesNotWorkOnWindows();

In .NET 6 we change the code to support the API, but only on Windows 10:

[UnsupportedOSPlatform("windows")]
[SupportedOSPlatform("windows10.0.1903")]
public void DoesNotWorkOnWindows();

Platform-specific API

[SupportedOSPlatform("ios12.0")]
[ObsoletedInOSPlatform("ios13.0")]
[UnsupportedOSPlatform("ios14.0")]
[SupportedOSPlatform("ipados13.0")]
public void OnlyWorksOniOS();

Related

Metadata

Metadata

Labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions