我有一个将DataTable填充到简单DTO对象的方法。为了简化,我将使用以下示例:
public enum Gender : int
{
Male = 1,
Female = 2
}
public class Person
{
//...
public Gender? MyGender { get; set; }
}
static void Main(string[] args)
{
int intValue = 2; // value from DB
var o = new Person();
var prop = o.GetType().GetProperty("MyGender");
prop.SetValue(o, intValue , null); // <- Exception
}
以上抛出:
类型为'System.Int32'的对象不能转换为类型为'System.Nullable`1 [Test.Program + Gender]'。
如果我将MyGender
声明为Gender
(不是Nullable),则一切正常。
如果我使用显式Cast prop.SetValue(o, (Gender)intValue, null);
但是,我不想(也不能)使用显式强制类型转换:(Gender)intValue
,因为我在创建代码时不了解底层的“硬”类型DTO对象。
我希望有类似(无法编译)的东西:
var propType = prop.PropertyType;
prop.SetValue(o, (propType)intValue, null);
我也尝试过:
public static dynamic Cast(dynamic obj, Type castTo)
{
return Convert.ChangeType(obj, castTo);
}
var propType = prop.PropertyType;
prop.SetValue(o, Cast(intValue, propType), null);
哪个抛出:
从'System.Int32'强制转换为 'System.Nullable`1 [[Test.Program + Gender ...]
我快死了。我有什么选择?
.NET Framework 4.6.2
答案 0 :(得分:3)
这是我能想到的最好的方法。进行了明确检查,以查看分配给该属性是否可为空,但是我认为您不能避免这种情况。
public static void Main(string[] args)
{
int intValue = 2; // value from DB
var o = new Person();
var prop = o.GetType().GetProperty("MyGender");
// Check whether the property is a nullable. If it is, get the type of underling enum
// Otherwise, get the type of the enum directly from the property
var enumType = Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType;
// Convert the int to the enum type
var convertedValue = Enum.ToObject(enumType, intValue);
prop.SetValue(o, convertedValue , null);
}
当然,如果所分配的属性不是枚举,则会发生不好的事情。 var convertedValue = enumType.IsEnum ? Enum.ToObject(enumType, intValue); : intValue;
可以避免这种情况。
答案 1 :(得分:0)
要考虑的“创造性”选项是:
var o = new Person();
o.MyGender = 0;
o.MyGender += intValue;
这看起来很奇怪,但是它确实起作用,因为常数 0具有内置的implicit cast枚举(其他数字没有)。
因此,将其设置为0,然后将其递增为您感兴趣的实际数字。这里的主要好处是您不会受到性能影响(和/或缺乏类型安全)。 您可能还想在代码中添加注释,说明执行原因。 ;)