Search code examples
c#reflectionenums

C# setting a nullable enum property with an int using reflection


I have a point in my code where I've got a PropertyInfo (referencing a nullable enum) and an instance of the type, and I want to set the enum value using an integer.

Here's a full example of what I'm trying to do:

using System;
using System.Reflection;

public enum MyEnum
{
    Value1,
    Value2,
}

public class MyClass
{
    public MyEnum? MyEnumValue { get; set; }
}

public class Program
{
    public static void Main()
    {
        PropertyInfo enumProperty = typeof(MyClass).GetProperty("MyEnumValue");
        MyClass myInstance = new();

        enumProperty.SetValue(myInstance, 1);
    }
}

When I run this, I get the error:

System.ArgumentException: Object of type 'System.Int32' cannot be converted to type 'System.Nullable`1[MyEnum]'.

(Compiler Explorer link for the above: https://godbolt.org/z/YdGf3sK87)

If I make MyEnumValue not nullable, the above code works fine (https://godbolt.org/z/EedzvGe4a)

How could I ensure that I can set this value using an integer? At compile time, I don't know the type of the enum (even through generics), although I can access the Type for it.

I've also tried:

var newValue = Convert.ChangeType(1, typeof(MyEnum));

Which gives me:

System.InvalidCastException: Invalid cast from 'System.Int32' to 'MyEnum'.

I had hoped that these two lines would have been equivalent:

var newValue = Convert.ChangeType(value, typeof(MyEnum));

and

var newValue = (MyEnum)value;

The second works (but requires a compile-time type), and the first doesn't. What I guess I'm eventually after is how to do the second option here while only having a Type object.


Solution

  • You're looking for Enum.ToObject.

    As the enum type is also potentially nullable, you'll need to get the underlying type first:

    var enumType = Nullable.GetUnderlyingType(enumProperty.PropertyType)
        ?? enumProperty.PropertyType;
    
    enumProperty.SetValue(myInstance, Enum.ToObject(enumType, 1));