Skip to content
This repository has been archived by the owner on Aug 8, 2024. It is now read-only.

Commit

Permalink
Add TypeConverter fallback to DefaultValueAttribute (#235)
Browse files Browse the repository at this point in the history
* Add TypeConverter fallback to DefaultValueAttribute (dotnet/coreclr#19354)

Signed-off-by: dotnet-bot <dotnet-bot@microsoft.com>

* Workaround for mcs

* Use mcs specific define
  • Loading branch information
MaximLipnin authored and marek-safar committed Jan 18, 2019
1 parent da51644 commit 8c0f4a9
Showing 1 changed file with 45 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,24 @@ public DefaultValueAttribute(Type type, string value)
// load an otherwise normal class.
try
{
if (type.IsSubclassOf(typeof(Enum)))
#if __MonoCS__
// 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)
{
_value = convertFromInvariantString(type, value);
}
#else
if (TryConvertFromInvariantString(type, value, out object convertedValue))
{
_value = convertedValue;
}
#endif
else if (type.IsSubclassOf(typeof(Enum)))
{
_value = Enum.Parse(type, value, true);
}
Expand All @@ -48,6 +65,29 @@ public DefaultValueAttribute(Type type, string value)
{
_value = Convert.ChangeType(value, type, CultureInfo.InvariantCulture);
}

return;
#if !__MonoCS__
// 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;
}
#endif
}
catch
{
Expand Down

0 comments on commit 8c0f4a9

Please sign in to comment.