While implementing a struct similar to Nullable<T>
I've found that PropertyInfo.SetValue
treats Nullable
type differently then others.
For Nullable property it can set value of underlying type
foo.GetType().GetProperty("NullableBool").SetValue(foo, true);
but for custom type it throws
System.ArgumentException: Object of type 'SomeType' cannot be converted to type NullableCase.CopyOfNullable 1[SomeType]
even if all conversion operators are overridden same way as in original Nullable<T>
Code to reproduce:
using System;
namespace NullableCase
{
/// <summary>
/// Copy of Nullable from .Net source code
/// without unrelated methodts for brevity
/// </summary>
public struct CopyOfNullable<T> where T : struct
{
private bool hasValue;
internal T value;
public CopyOfNullable(T value)
{
this.value = value;
this.hasValue = true;
}
public bool HasValue
{
get
{
return hasValue;
}
}
public T Value
{
get
{
if (!hasValue)
{
throw new InvalidOperationException();
}
return value;
}
}
public static implicit operator CopyOfNullable<T>(T value)
{
return new CopyOfNullable<T>(value);
}
public static explicit operator T(CopyOfNullable<T> value)
{
return value.Value;
}
}
class Foo
{
public Nullable<bool> NullableBool { get; set; }
public CopyOfNullable<bool> CopyOfNullablBool { get; set; }
}
class Program
{
static void Main(string[] args)
{
Foo foo = new Foo();
foo.GetType().GetProperty("NullableBool").SetValue(foo, true);
foo.GetType().GetProperty("CopyOfNullablBool").SetValue(foo, true); //here we get ArgumentException
}
}
}
Why does PropertyInfo.SetValue
fails for CopyOfNullable
type and passes for Nullable<T>
?
Nullable<T>
has special support within the CLR type system to automatically convert from T
.
In fact, it is impossible to have a boxed instance of Nullable<T>
; nullable values box to either to underlying value or an actual null.
This is one of the very few magical types in the BCL; it is impossible to duplicate.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With