From 5a7336216e6eedabc3f09e7d864248ecafcfcb08 Mon Sep 17 00:00:00 2001 From: Steve Harter Date: Wed, 31 Jul 2024 11:37:58 -0500 Subject: [PATCH 1/2] Support [DefaultValue] when new feature switch is disabled --- .../DefaultValueAttributeTests.cs | 48 +++++++++++++++++++ ...nentModel.TypeConverter.TrimmingTests.proj | 3 ++ .../ComponentModel/DefaultValueAttribute.cs | 7 ++- 3 files changed, 56 insertions(+), 2 deletions(-) create mode 100644 src/libraries/System.ComponentModel.TypeConverter/tests/TrimmingTests/DefaultValueAttributeTests.cs diff --git a/src/libraries/System.ComponentModel.TypeConverter/tests/TrimmingTests/DefaultValueAttributeTests.cs b/src/libraries/System.ComponentModel.TypeConverter/tests/TrimmingTests/DefaultValueAttributeTests.cs new file mode 100644 index 00000000000000..a5a7802989e21c --- /dev/null +++ b/src/libraries/System.ComponentModel.TypeConverter/tests/TrimmingTests/DefaultValueAttributeTests.cs @@ -0,0 +1,48 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.ComponentModel; +using System.Reflection; + +/// +/// Tests that using the [DefaultValue] ctor(Type, String) throws and other ctors with primitive values do not throw. +/// +class Program +{ + static int Main(string[] args) + { + object value; + DefaultValueAttribute attribute; + + // Primitive types should not throw. + attribute = typeof(TestClass).GetProperty(nameof(TestClass.MyPropertyWithDefaultValue))!.GetCustomAttribute()!; + value = attribute.Value; + if (value == null || (int)value != 42) + { + return -1; + } + + attribute = typeof(TestClass).GetProperty(nameof(TestClass.MyPropertyWithDefaultValueUsingTypeConverter))!.GetCustomAttribute()!; + try + { + value = attribute.Value; + } + catch (ArgumentException) + { + // The System.ComponentModel.DefaultValueAttribute.IsSupported feature switch is off so ArgumentException should be thrown. + return 100; + } + + return -2; + } +} + +public class TestClass +{ + [DefaultValue(42)] + public int MyPropertyWithDefaultValue { get; set; } + + [DefaultValue(typeof(int), "42")] + public int MyPropertyWithDefaultValueUsingTypeConverter { get; set; } +} diff --git a/src/libraries/System.ComponentModel.TypeConverter/tests/TrimmingTests/System.ComponentModel.TypeConverter.TrimmingTests.proj b/src/libraries/System.ComponentModel.TypeConverter/tests/TrimmingTests/System.ComponentModel.TypeConverter.TrimmingTests.proj index ecd2a44e3df339..928c5c8b781e07 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/tests/TrimmingTests/System.ComponentModel.TypeConverter.TrimmingTests.proj +++ b/src/libraries/System.ComponentModel.TypeConverter/tests/TrimmingTests/System.ComponentModel.TypeConverter.TrimmingTests.proj @@ -3,6 +3,9 @@ + + System.ComponentModel.DefaultValueAttribute.IsSupported + diff --git a/src/libraries/System.Private.CoreLib/src/System/ComponentModel/DefaultValueAttribute.cs b/src/libraries/System.Private.CoreLib/src/System/ComponentModel/DefaultValueAttribute.cs index 92f3806e57ddcb..cb694561b52a92 100644 --- a/src/libraries/System.Private.CoreLib/src/System/ComponentModel/DefaultValueAttribute.cs +++ b/src/libraries/System.Private.CoreLib/src/System/ComponentModel/DefaultValueAttribute.cs @@ -28,6 +28,7 @@ public class DefaultValueAttribute : Attribute #pragma warning disable IL4000 internal static bool IsSupported => AppContext.TryGetSwitch("System.ComponentModel.DefaultValueAttribute.IsSupported", out bool isSupported) ? isSupported : true; #pragma warning restore IL4000 + private static readonly object? s_throwSentinel = IsSupported ? null : new(); /// /// Initializes a new instance of the @@ -44,6 +45,7 @@ public DefaultValueAttribute( Debug.Assert(IsSupported, "Runtime instantiation of this attribute is not allowed with trimming."); if (!IsSupported) { + _value = s_throwSentinel; return; } @@ -245,21 +247,22 @@ public virtual object? Value { get { - if (!IsSupported) + if (!IsSupported && object.ReferenceEquals(_value, s_throwSentinel)) { throw new ArgumentException(SR.RuntimeInstanceNotAllowed); } + return _value; } } - public override bool Equals([NotNullWhen(true)] object? obj) { if (obj == this) { return true; } + if (obj is not DefaultValueAttribute other) { return false; From 77ed3b1559bf3841f486b916ab72de1ae56e3a7a Mon Sep 17 00:00:00 2001 From: Steve Harter Date: Wed, 31 Jul 2024 13:18:25 -0500 Subject: [PATCH 2/2] Change object.ReferenceEquals() to ReferenceEquals() --- .../src/System/ComponentModel/DefaultValueAttribute.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/ComponentModel/DefaultValueAttribute.cs b/src/libraries/System.Private.CoreLib/src/System/ComponentModel/DefaultValueAttribute.cs index cb694561b52a92..40d082a8c406e8 100644 --- a/src/libraries/System.Private.CoreLib/src/System/ComponentModel/DefaultValueAttribute.cs +++ b/src/libraries/System.Private.CoreLib/src/System/ComponentModel/DefaultValueAttribute.cs @@ -247,7 +247,7 @@ public virtual object? Value { get { - if (!IsSupported && object.ReferenceEquals(_value, s_throwSentinel)) + if (!IsSupported && ReferenceEquals(_value, s_throwSentinel)) { throw new ArgumentException(SR.RuntimeInstanceNotAllowed); }