【问题标题】:How to set an Int16 value to a Nullable<Enum> property using reflection?如何使用反射将 Int16 值设置为 Nullable<Enum> 属性?
【发布时间】:2011-12-22 14:43:33
【问题描述】:

我需要这样做:-

MyClass.cs

using System;
using System.Collections.Generic;
using System.Text;

namespace set_property__Enum_To_Nullable_Enum
{
    public enum MyEnum : short
    {
        One, 
        Two, 
        Three 
    }

    public class MyClass
    {
        public string MyStringProperty { get; set; }
        public MyEnum? MyEnumProperty { get; set; }

        public void ShowAll(string message)
        {
            Console.WriteLine(message);            
            Console.WriteLine("String   = " + MyStringProperty);
            Console.WriteLine("Enum   = " + MyEnumProperty.Value);
        }
    }
}

Program.cs

using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;

namespace set_property__Enum_To_Nullable_Enum
{
    class Program
    {
        static void Main(string[] args)
        {
            //Names
            string myAssemblyName = "MyAssembly";
            string myNamespaceName = "set_property__Enum_To_Nullable_Enum";
            string myClassName = "MyClass";
            string propertyNameOne = "MyStringProperty";
            string propertyNameTwo = "MyEnumProperty";

            //Data            
            string myString = "Hello World!";
            short myInteger = 1;

            //Preprocessing
            Assembly myAssmbly = Assembly.Load(myAssemblyName);
            Type myType = myAssmbly.GetType(myNamespaceName + "." + myClassName);

            //Create class-instance
            object objectInstance = Activator.CreateInstance(myType);

            //Set property-values
            PropertyInfo propertyInfoOne = myType.GetProperty(propertyNameOne);
            propertyInfoOne.SetValue(objectInstance, myString, null);

            PropertyInfo propertyInfoTwo = myType.GetProperty(propertyNameTwo);
            propertyInfoTwo.SetValue(objectInstance, myInteger, null);//<---------------

            //Call method
            myType.InvokeMember("ShowAll",
                                        BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.Public,
                                        null,
                                        objectInstance,
                                        new object[] { "My name is Khan" });

            string end = string.Empty;
        }
    }
}

但 Int32 值不会自动转换为 MyEnum。

在特定行,正在生成异常。

Object of type 'System.Int16' cannot be converted to type 'System.Nullable`1[set_property__Enum_To_Nullable_Enum.MyEnum]'.

怎么做?

编辑

我需要进一步的帮助!

Enum.ToObject() 无法处理 null。

【问题讨论】:

    标签: c# reflection .net-2.0


    【解决方案1】:

    好的,在这种情况下您需要使用Enum.ToObject,因为您使用的是反射。但是您还需要解开 nullable 以使用它,Nullable.GetUnderlyingType 为您做的。

    那么,你需要得到MyEnum对应的Type

    Type nullableEnumType = propertyInfoTwo.PropertyType;
    Type enumType = Nullable.GetUnderlyingType(nullableEnumType);
    

    然后使用Enum.ToObject 生成带有您指定值的MyEnum 的盒装实例:

    object enumValue = Enum.ToObject(enumType, myInteger);
    

    所以,把它们放在一起:

    object enumValue = Enum.ToObject(Nullable.GetUnderlyingType(propertyInfoTwo.PropertyType), myInteger);
    propertyInfoTwo.SetValue(objectInstance, enumValue, null);
    

    编辑:

    如果myInteger 本身可以为空,您应该使用:

    object enumValue = 
        myInteger.HasValue
            ? Enum.ToObject(Nullable.GetUnderlyingType(propertyInfoTwo.PropertyType), myInteger.Value);
            : null;
    

    【讨论】:

    • 这不是我的问题。 Enum.ToObject() 无法处理 null。因此,每当 myInteger==null 时,函数调用都会失败。如何解决?
    • @Saqib:这确实解决了您的问题。如果myInteger 不为null (myInteger.HasValue),它会在myInteger 的值上调用Enum.ToObject,否则它会将null 分配给enumValue
    • 您的回答让我可以测试:Nullable.GetUnderlyingType(nullableEnumType).IsEnum ~ 谢谢!
    【解决方案2】:

    就投吧?

    propertyInfoTwo.SetValue(objectInstance, (MyEnum?)myInteger, null);
    

    【讨论】:

    • 此解决方案适用于您发布的代码。如果这不是您需要的解决方案,请发布相关代码。恐怕我没有水晶球。
    • 它必须适用于任何 Enum 类型,而不仅仅是 MyEnum。无论如何,我找到了我的解决方案。
    【解决方案3】:

    使用 int 代替 short 或

    enum MyEnum : Int16 
    

    或将 short 转换为 int。

    更新: 试试

    short? MyInteger = 1;
    

    【讨论】:

    • 更新后的解决方案无法使用。因为,这个短值将来自数据库表。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-03
    • 2012-08-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多