runtime: DefaultValueAttribute missing unsigned int / unsigned long constructor
Latest proposal
Rationale and Usage
As has already been explained, using DefaultValueAttribute
with one of the problematic types (unsigned integer types and sbyte
) in C# ends up using a widening conversion and so the boxed Value
ends up with an unexpected type. The proposal is to add constructor overloads so that the conversions don’t happen and Value
gets the expected type.
The usage stays the same as before, e.g. [DefaultValue(UInt64.MaxValue)]
.
Doing this would be technically a source breaking change, since recompiling existing code would end up with a different type for the boxed Value
. (Arguably, it would be a better type, but that doesn’t change the fact that someone could rely on the old behavior.)
Proposed API
public class DefaultValueAttribute : Attribute
{
// existing constructor overloads:
public DefaultValueAttribute(Type type, string value);
public DefaultValueAttribute(char value);
public DefaultValueAttribute(byte value);
public DefaultValueAttribute(short value);
public DefaultValueAttribute(int value);
public DefaultValueAttribute(long value);
public DefaultValueAttribute(float value);
public DefaultValueAttribute(double value);
public DefaultValueAttribute(bool value);
public DefaultValueAttribute(string value);
public DefaultValueAttribute(object value);
// added constructor overloads:
public DefaultValueAttribute(sbyte value);
public DefaultValueAttribute(ushort value);
public DefaultValueAttribute(uint value);
public DefaultValueAttribute(ulong value);
}
Original proposal
Most numeric types have their constructor but not the unsigned ones.
As a result, if you write that code:
new DefaultValueAttribute(UInt64.MaxValue);
The float constructor will be called as the compiler seems to avoid the constructor that needs boxing.
Removing all explicit constructor that takes numeric types solve the issue.
They all points to the same code that will box the value anyway:
/// <devdoc>
/// <para>Initializes a new instance of the <see cref='System.ComponentModel.DefaultValueAttribute'/> class using a Unicode
/// character.</para>
/// </devdoc>
public DefaultValueAttribute(char value) {
this.value = value;
}
About this issue
- Original URL
- State: closed
- Created 8 years ago
- Comments: 15 (12 by maintainers)
Commits related to this issue
- DefaultValueAttribute missing unsigned int / unsigned long constructor. See https://github.com/dotnet/corefx/issues/11465 — committed to steveharter/dotnet_corefx by AlexRadch 8 years ago
My API proposal speclet:
Rationale and Usage
As has already been explained, using
DefaultValueAttribute
with one of the problematic types (unsigned integer types andsbyte
) in C# ends up using a widening conversion and so the boxedValue
ends up with an unexpected type. The proposal is to add constructor overloads so that the conversions don’t happen andValue
gets the expected type.The usage stays the same as before, e.g.
[DefaultValue(UInt64.MaxValue)]
.Doing this would be technically a source breaking change, since recompiling existing code would end up with a different type for the boxed
Value
. (Arguably, it would be a better type, but that doesn’t change the fact that someone could rely on the old behavior.)Proposed API