Description
Background and motivation
With our recent adoptions of the [Experimental]
attribute, we found it would have been valuable to add a custom message for the experimental APIs to add context for why the API is marked as experimental. The desired experience would be similar to that of [Obsolete]
where a custom message can be provided in addition to the custom diagnostic ID.
API Proposal
[System.AttributeUsageAttribute(System.AttributeTargets.Assembly | System.AttributeTargets.Class |
System.AttributeTargets.Constructor | System.AttributeTargets.Delegate | System.AttributeTargets.Enum |
System.AttributeTargets.Event | System.AttributeTargets.Field | System.AttributeTargets.Interface |
System.AttributeTargets.Method | System.AttributeTargets.Module | System.AttributeTargets.Property |
System.AttributeTargets.Struct, Inherited=false)]
public sealed partial class ExperimentalAttribute : System.Attribute
{
public ExperimentalAttribute(string diagnosticId) { }
+ public ExperimentalAttribute(string diagnosticId, string? message) { }
public string DiagnosticId { get { throw null; } }
+ public string? Message { get { throw null; } }
public string? UrlFormat { get { throw null; } set { } }
}
API Usage
namespace System.Runtime.Intrinsics;
public abstract partial class X86Base
{
[Experimental("SYSLIB5004", "X86Base.DivRem is experimental since performance is not as optimized as T.DivRem",
UrlFormat = "https://aka.ms/dotnet-warnings/{0}")]
public static (uint Quotient, uint Remainder) DivRem(uint lower, uint upper, uint divisor) { throw null; }
{
}
}
Alternative Designs
Create a new mechanism for registering the messages. Or keep the status quo and rely on the linked documentation to provide fuller context.
Risks
We will need to follow the model we applied with ObsoleteAttribute
where the compiler respects whichever ExperimentalAttribute
is defined for the assembly using it, where that type might have Message
or might not. When applying this attribute down-level to targets before Message
was introduced, libraries can opt to include an internal copy of the class that includes the property so the message can be applied.
We will need to discuss the format of the compiler message, localization, and determine if the default message should be emitted in addition to the custom message, or if only the custom message would be emitted. We should be able to follow the [Obsolete]
attribute behavior.