[英]Nullable problems with Activator.CreateInstance and Convert.ChangeType
I have a third party library which sets a given objects property using reflection as follows. 我有一个第三方库,它使用反射如下设置给定的对象属性。 (This is the simplified version) (这是简化版)
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);
}
And We have class with a nullable property 而且我们有一个带有可空属性的类
class Test
{
public int? X { get; set; }
}
When I write the following code, it says it cannot convert int
to int?
当我编写以下代码时,它说不能将int
转换为int?
var t = new Test();
Set(t, "X", 1);
Since Nullable does not implement IConvertible it makes sense. 由于Nullable没有实现IConvertible,所以这很有意义。 Then I decided to write a method which returns the nullable version of a given value typed object. 然后,我决定编写一个方法,该方法返回给定值类型对象的可空版本。
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 });
}
I hoped to use this method as follows. 我希望按如下方式使用此方法。
var t = new Test();
Set(t, "X", MakeNullable(1));
But it still says it cannot convert int
to int?
但是它仍然说不能将int
转换为int?
. 。 When I debug typeof(Nullable<>).MakeGenericType(obj.GetType())
equals int?
当我调试typeof(Nullable<>).MakeGenericType(obj.GetType())
等于int?
but Activator.CreateInstace
returns an int
value not int?
但是Activator.CreateInstace
返回的是int
值而不是int?
So this is my case... Any help? 这就是我的情况...有什么帮助吗?
Try this code... 试试这个代码...
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);
}
}
from here Convert.ChangeType() fails on Nullable Types by LukeH 从这里,LukeH的Nullable Types上的Convert.ChangeType()失败
UPDATE : Hide base method. 更新:隐藏基本方法。
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; }
}
} }
This should work: 这应该工作:
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.