-
Notifications
You must be signed in to change notification settings - Fork 4.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Disable default and ambient attribute at runtime with a feature switch #100416
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,7 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
|
||
using System.Diagnostics; | ||
using System.Diagnostics.CodeAnalysis; | ||
using System.Globalization; | ||
using System.Reflection; | ||
|
@@ -22,6 +23,9 @@ public class DefaultValueAttribute : Attribute | |
// Delegate ad hoc created 'TypeDescriptor.ConvertFromInvariantString' reflection object cache | ||
private static object? s_convertFromInvariantString; | ||
|
||
[FeatureSwitchDefinition("System.ComponentModel.DefaultValueAttribute.IsSupported")] | ||
internal static bool IsSupported => AppContext.TryGetSwitch("System.ComponentModel.DefaultValueAttribute.IsSupported", out bool isSupported) ? isSupported : true; | ||
|
||
/// <summary> | ||
/// Initializes a new instance of the <see cref='DefaultValueAttribute'/> | ||
/// class, converting the specified value to the specified type, and using the U.S. English | ||
|
@@ -35,6 +39,12 @@ public DefaultValueAttribute( | |
// The null check and try/catch here are because attributes should never throw exceptions. | ||
// We would fail to load an otherwise normal class. | ||
|
||
if (!IsSupported) | ||
{ | ||
Debug.Assert(!IsSupported, "Runtime instantiation of this attribute is not allowed."); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Assert vs. throw approaches - was the Assert approach taken to be backwards compatible here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, respecting the comments on the type so as not to throw |
||
return; | ||
} | ||
|
||
if (type == null) | ||
{ | ||
return; | ||
|
@@ -229,7 +239,18 @@ public DefaultValueAttribute(ulong value) | |
/// <summary> | ||
/// Gets the default value of the property this attribute is bound to. | ||
/// </summary> | ||
public virtual object? Value => _value; | ||
public virtual object? Value | ||
{ | ||
get | ||
{ | ||
if (!IsSupported) | ||
{ | ||
throw new ArgumentException(SR.RuntimeInstanceNotAllowed); | ||
} | ||
return _value; | ||
} | ||
} | ||
|
||
|
||
public override bool Equals([NotNullWhen(true)] object? obj) | ||
{ | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this is made
readonly
then the JIT should be able to remove code as well (for cases when the trimmer isn't used). (requires adding a readonly field + a property)@sbomer is my
readonly
comment above still applicable? Do we have guidance for this?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The sanctioned pattern that should be optimizable by the JIT is a static bool property with a getter (see original design at https://github.com/dotnet/designs/blob/main/accepted/2020/feature-switch.md). I don't believe a field is necessary, but haven't checked the JIT codegen. @vitek-karas
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, in addition to perhaps supporting JIT, a
static readonly
field accessed by the property would cache the value, soAppContext.TryGetSwitch()
doesn't get called every time (again, only for non-trimmed scenarios).