-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
Allow DefaultValueAttribute
with primitives when System.ComponentModel.DefaultValueAttribute.IsSupported
disabled
#103542
Comments
Tagging subscribers to this area: @dotnet/area-system-componentmodel |
Wouldn't the flag name become incredibly misleading though? It clearly states that the entire attribute "should not be supported". |
@julealgon it's not published in GA release, so can be renamed |
@LakshanF @steveharter please have a look |
@OwnageIsMagic, thanks for the valuable feedback on the To help better understand your use case, could you give more details on your scenario please? The feature switch was added to help with trimming and non-trimming scenarios would have this feature set to true by default (and should not have any problems using |
@LakshanF I'm exploring aot for minimizing winforms app bundle and just disabled every runtime feature. Interface works ok, but XmlSerialzer is throwing this exception. Enabling it doesn't change exe size, so it seems like TypeDescriptor is trimmed anyway (didn't check), but disabling just make things bad without any benefit. |
Per offline discussion with @LakshanF, removing the check in the getter seems reasonable: https://github.com/dotnet/runtime/blob/main/src/libraries/System.Private.CoreLib/src/System/ComponentModel/DefaultValueAttribute.cs#L248-L251. However, we could just remove the check the (Type, string) ctor not the primitive ctors. This means adding a new flag to track that. |
@steveharter no need for another flag, just rename this one to something like private readonly static object? throwSentinel = IsSupported ? null : new();
public DefaultValueAttribute(Type type, string? value)
{
if (type == null)
{
return;
}
try
{
if (type == typeof(TimeSpan) && value != null)
{
_value = TimeSpan.Parse(value);
}
else if (type.IsSubclassOf(typeof(Enum)) && value != null)
{
_value = Enum.Parse(type, value, true);
}
else if (type.IsAssignableFrom(typeof(IConvertible)))
{
try { _value = Convert.ChangeType(value, type, CultureInfo.InvariantCulture); }
catch { }
}
// I reordered if blocks, can we allow this change?
{
Debug.Assert(IsSupported, "TODO");
if (!IsSupported)
{
_value = throwSentinel;
return;
}
_ = TryConvertFromInvariantString(type, value, out object? _value);
static bool TryConvertFromInvariantString(...) { ... }
}
}
catch
{
}
}
public virtual object? Value
{
get
{
if (!IsSupported && _value == throwSentinel)
{
throw new ArgumentException(SR.RuntimeInstanceNotAllowed);
}
return _value;
}
} |
Description
DefaultValueAttribute.Value
throws on access (due to #100416) whenSystem.ComponentModel.DefaultValueAttribute.IsSupported
switch isfalse
and it breaksXmlSerializer
and other serializers/reflection. But it's very common to use not(Type, string)
overload, but 1 arg primitive which do not useTypeDescriptor
API family.Reproduction Steps
Expected behavior
No exception, use constructor arg as is.
Actual behavior
Workaround
set
_value
to some sentinel ifTypeDescriptor
is required and throw only in this case.The text was updated successfully, but these errors were encountered: