[英]Nullable problems with Activator.CreateInstance and Convert.ChangeType
我有一个第三方库,它使用反射如下设置给定的对象属性。 (这是简化版)
public void Set(object obj, string prop, object value) {
var propInf = obj.GetType().GetProperty(prop);
value = Convert.ChangeType(value, propInf.PropertyType);
propInf.SetValue(obj, value, null);
}
而且我们有一个带有可空属性的类
class Test
{
public int? X { get; set; }
}
当我编写以下代码时,它说不能将int
转换为int?
var t = new Test();
Set(t, "X", 1);
由于Nullable没有实现IConvertible,所以这很有意义。 然后,我决定编写一个方法,该方法返回给定值类型对象的可空版本。
public object MakeNullable(object obj) {
if(obj == null || !obj.GetType().IsValueType)
throw new Exception("obj must be value type!");
return Activator.CreateInstance(
typeof(Nullable<>).MakeGenericType(obj.GetType()),
new[] { obj });
}
我希望按如下方式使用此方法。
var t = new Test();
Set(t, "X", MakeNullable(1));
但是它仍然说不能将int
转换为int?
。 当我调试typeof(Nullable<>).MakeGenericType(obj.GetType())
等于int?
但是Activator.CreateInstace
返回的是int
值而不是int?
这就是我的情况...有什么帮助吗?
试试这个代码...
public void Set(object obj, string prop, object value)
{
//var propInf = obj.GetType().GetProperty(prop);
//value = Convert.ChangeType(value, propInf.PropertyType);
//propInf.SetValue(obj, value, null);
var property = obj.GetType().GetProperty(prop);
if (property != null)
{
Type t = Nullable.GetUnderlyingType(property.PropertyType)
?? property.PropertyType;
object safeValue = (value == null) ? null
: Convert.ChangeType(value, t);
property.SetValue(obj, safeValue, null);
}
}
从这里,LukeH的Nullable Types上的Convert.ChangeType()失败
更新:隐藏基本方法。
namespace ConsoleApplication2
{
using System;
using System.Collections.Generic;
using System.Linq;
internal class Program
{
private static void Main(string[] args)
{
EnterPoint t = new EnterPoint();
t.BeginProcess();
}
}
public class EnterPoint
{
public void BeginProcess()
{
var t = new Test(); //Object
try
{
baseDllMethod m = new baseDllMethod(); //Your DLL
m.Set(t, "X", 1); //Problem Method, this give you error
}
catch (Exception ex)
{
Console.WriteLine("ERROR EN DLL METHOD");
}
xyz_D der = new xyz_D(); //Derivated method
der.Set(t, "X", 1) ; //HIDE BASE METHOD
}
}
public class baseDllMethod //YOUR DLL HERE
{
public void Set(object obj, string prop, object value)
{
var propInf = obj.GetType().GetProperty(prop);
value = Convert.ChangeType(value, propInf.PropertyType);
propInf.SetValue(obj, value, null);
}
}
public class xyz_D : baseDllMethod //Inherits
{
public new void Set(object obj, string prop, object value) //Hide base method
{
var property = obj.GetType().GetProperty(prop);
if (property != null)
{
Type t = Nullable.GetUnderlyingType(property.PropertyType)
?? property.PropertyType;
object safeValue = (value == null) ? null
: Convert.ChangeType(value, t);
property.SetValue(obj, safeValue, null);
}
}
}
public class Test //Your Object
{
public int? X { get; set; }
}
}
这应该工作:
public static object ChangeType(object value, Type conversionType)
{
if (conversionType.IsGenericType && conversionType.GetGenericTypeDefinition() == typeof(Nullable<>))
{
if (value == null)
return null;
var nullableConverter = new NullableConverter(conversionType);
conversionType = nullableConverter.UnderlyingType;
}
return Convert.ChangeType(value, conversionType);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.