Skip to content

Commit

Permalink
Add TypeConverter fallback to DefaultValueAttribute (dotnet/coreclr#1…
Browse files Browse the repository at this point in the history
…9354)

Signed-off-by: dotnet-bot <dotnet-bot@microsoft.com>
  • Loading branch information
MarcoRossignoli authored and MaximLipnin committed Jan 14, 2019
1 parent 7d84ec4 commit 5c323de
Showing 1 changed file with 31 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,8 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.Runtime.InteropServices;
using System.Threading;

namespace System.ComponentModel
{
Expand All @@ -23,6 +20,9 @@ public class DefaultValueAttribute : Attribute
/// </devdoc>
private object _value;

// Delegate ad hoc created 'TypeDescriptor.ConvertFromInvariantString' reflection object cache
static object s_convertFromInvariantString;

/// <devdoc>
/// <para>Initializes a new instance of the <see cref='System.ComponentModel.DefaultValueAttribute'/> class, converting the
/// specified value to the
Expand All @@ -36,7 +36,11 @@ public DefaultValueAttribute(Type type, string value)
// load an otherwise normal class.
try
{
if (type.IsSubclassOf(typeof(Enum)))
if (TryConvertFromInvariantString(type, value, out object convertedValue))
{
_value = convertedValue;
}
else if (type.IsSubclassOf(typeof(Enum)))
{
_value = Enum.Parse(type, value, true);
}
Expand All @@ -48,6 +52,28 @@ public DefaultValueAttribute(Type type, string value)
{
_value = Convert.ChangeType(value, type, CultureInfo.InvariantCulture);
}

return;

// Looking for ad hoc created TypeDescriptor.ConvertFromInvariantString(Type, string)
bool TryConvertFromInvariantString(Type typeToConvert, string stringValue, out object conversionResult)
{
conversionResult = null;

// lazy init reflection objects
if (s_convertFromInvariantString == null)
{
Type typeDescriptorType = Type.GetType("System.ComponentModel.TypeDescriptor, System.ComponentModel.TypeConverter", throwOnError: false);
Volatile.Write(ref s_convertFromInvariantString, typeDescriptorType == null ? new object() : Delegate.CreateDelegate(typeof(Func<Type, string, object>), typeDescriptorType, "ConvertFromInvariantString", ignoreCase: false));
}

if (!(s_convertFromInvariantString is Func<Type, string, object> convertFromInvariantString))
return false;

conversionResult = convertFromInvariantString(typeToConvert, stringValue);

return true;
}
}
catch
{
Expand Down

0 comments on commit 5c323de

Please sign in to comment.