Add helper method to describe features supported by the runtime · Issue #20623 · dotnet/runtime (original) (raw)
As we ramp the compiler and runtimes together, we want to prevent users from compiling code that we know will fail against a certain runtime.
For instance, we plan for newer runtimes to support default implementations in interface, and the compiler should be able to detect that you're compiling against an older runtime without that support.
Previously, this was done by having the compiler look for APIs that were added coincidentally with the new support. But as we expect to run into this problem more often, it makes sense to have a systematic design for testing feature support.
The main consumer of this API would be the compiler. Whenever it needs to check for runtime support, it would look for the corresponding well-known enum member (for instance, System.Runtime.CompilerServices.RuntimeCapabilities.SupportsDefaultImplementation
). If the member exists, then the feature check is successful (the feature is supported). The value for that enum member is ignored.
A number of feature requests or known bugs interfering with compiler or language evolution is documented in dotnet/csharplang#251
Proposed API
(Updated after API review 3/28/2017)
(Updated to use "const" instead of "static readonly" after further discussion 4/13/2017)
namespace System.Runtime.CompilerServices { public static class RuntimeFeature { // Presence of the field indicates runtime support public const string FixedGenericAttributes = nameof(FixedGenericAttributes); public const string DefaultImplementation = nameof(DefaultImplementation);
// Runtime check
public static bool IsSupported(string feature);
}
}
// Usage
if (RuntimeFeature.IsSupported("SomeNewerFeature") { // Use feature when emitting code at runtime (CodeDOM, RefEmit etc) }
- Static detection. The presence of a field alone indicates whether the code compiled against it can rely on the runtime providing the feature. This allows us to model runtime capabilities like any other API, which includes leveraging our existing infrastructure for detecting breaking changes. Also, this allows us to express this in .NET Standard and will version like any other API.
- Runtime detection. There are some (very limited) scenarios where someone might want to do feature detection at runtime, in particular runtime code generation using RefEmit. We don't expect many developers to call this API. Usage of this API will always involve a literal, as having a field in scope would imply
IsSupported
must returntrue
. Developers using light-up would discover the strings by looking at the documentation of a particular .NET platform.
Original proposed API
(rejected in favor of the one above)
namespace System.Runtime.CompilerServices { public enum RuntimeFeatures { FixedGenericAttributes, SupportsDefaultImplementation, // ... this list would grow over time } }
Maintenance process
Adding new enum members would go through the standard API review process.
The main requirement is that enum names should mean the same thing across the different runtimes (desktop, core, RT, mono).
Also, there needs to be documented agreement between the runtimes and compilers about the meaning of each new member.
CC @gafter, @AlekseyTs, @VSadov, @jaredpar