Skip to content

Commit 1009a1c

Browse files
authored
Support [DefaultValue] when new feature switch is disabled (#105766)
1 parent cc2f601 commit 1009a1c

File tree

3 files changed

+56
-2
lines changed

3 files changed

+56
-2
lines changed
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using System;
5+
using System.ComponentModel;
6+
using System.Reflection;
7+
8+
/// <summary>
9+
/// Tests that using the [DefaultValue] ctor(Type, String) throws and other ctors with primitive values do not throw.
10+
/// </summary>
11+
class Program
12+
{
13+
static int Main(string[] args)
14+
{
15+
object value;
16+
DefaultValueAttribute attribute;
17+
18+
// Primitive types should not throw.
19+
attribute = typeof(TestClass).GetProperty(nameof(TestClass.MyPropertyWithDefaultValue))!.GetCustomAttribute<DefaultValueAttribute>()!;
20+
value = attribute.Value;
21+
if (value == null || (int)value != 42)
22+
{
23+
return -1;
24+
}
25+
26+
attribute = typeof(TestClass).GetProperty(nameof(TestClass.MyPropertyWithDefaultValueUsingTypeConverter))!.GetCustomAttribute<DefaultValueAttribute>()!;
27+
try
28+
{
29+
value = attribute.Value;
30+
}
31+
catch (ArgumentException)
32+
{
33+
// The System.ComponentModel.DefaultValueAttribute.IsSupported feature switch is off so ArgumentException should be thrown.
34+
return 100;
35+
}
36+
37+
return -2;
38+
}
39+
}
40+
41+
public class TestClass
42+
{
43+
[DefaultValue(42)]
44+
public int MyPropertyWithDefaultValue { get; set; }
45+
46+
[DefaultValue(typeof(int), "42")]
47+
public int MyPropertyWithDefaultValueUsingTypeConverter { get; set; }
48+
}

src/libraries/System.ComponentModel.TypeConverter/tests/TrimmingTests/System.ComponentModel.TypeConverter.TrimmingTests.proj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33

44
<ItemGroup>
55
<TestConsoleAppSourceFiles Include="ComObjectTypeTest.cs" />
6+
<TestConsoleAppSourceFiles Include="DefaultValueAttributeTests.cs">
7+
<DisabledFeatureSwitches>System.ComponentModel.DefaultValueAttribute.IsSupported</DisabledFeatureSwitches>
8+
</TestConsoleAppSourceFiles>
69
<TestConsoleAppSourceFiles Include="InterfaceTypeTest.cs" />
710
<TestConsoleAppSourceFiles Include="TypeConverterIsReadOnly.cs" />
811
<TestConsoleAppSourceFiles Include="TypeConverterTest.cs" />

src/libraries/System.Private.CoreLib/src/System/ComponentModel/DefaultValueAttribute.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ public class DefaultValueAttribute : Attribute
2828
#pragma warning disable IL4000
2929
internal static bool IsSupported => AppContext.TryGetSwitch("System.ComponentModel.DefaultValueAttribute.IsSupported", out bool isSupported) ? isSupported : true;
3030
#pragma warning restore IL4000
31+
private static readonly object? s_throwSentinel = IsSupported ? null : new();
3132

3233
/// <summary>
3334
/// Initializes a new instance of the <see cref='DefaultValueAttribute'/>
@@ -44,6 +45,7 @@ public DefaultValueAttribute(
4445
Debug.Assert(IsSupported, "Runtime instantiation of this attribute is not allowed with trimming.");
4546
if (!IsSupported)
4647
{
48+
_value = s_throwSentinel;
4749
return;
4850
}
4951

@@ -245,21 +247,22 @@ public virtual object? Value
245247
{
246248
get
247249
{
248-
if (!IsSupported)
250+
if (!IsSupported && ReferenceEquals(_value, s_throwSentinel))
249251
{
250252
throw new ArgumentException(SR.RuntimeInstanceNotAllowed);
251253
}
254+
252255
return _value;
253256
}
254257
}
255258

256-
257259
public override bool Equals([NotNullWhen(true)] object? obj)
258260
{
259261
if (obj == this)
260262
{
261263
return true;
262264
}
265+
263266
if (obj is not DefaultValueAttribute other)
264267
{
265268
return false;

0 commit comments

Comments
 (0)