原本型別轉換
pro.SetValue(objT, (row[pro.Name] == DBNull.Value ? null : Convert.ChangeType(row[pro.Name], pI.PropertyType)), null);
改成
pro.SetValue(objT, (row[pro.Name] == DBNull.Value ? null : ChangeType(row[pro.Name], pI.PropertyType)), null);
//轉換為可為 Null 的型別
public static object ChangeType(object value, Type conversion)
{
var t = conversion;
if (t.IsGenericType && t.GetGenericTypeDefinition().Equals(typeof(Nullable<>)))
{
if (value == null)
{
return null;
}
t = Nullable.GetUnderlyingType(t);
}
return Convert.ChangeType(value, t);
}
錯誤訊息:
Invalid cast from 'System.Int32' to 'System.Nullable`
從 'System.Decimal' 至 'System.Nullable`1[[System.Decimal, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]' 的轉換無效。
參考:
Invalid cast from 'System.Int32' to 'System.Nullable`1[[System.Int32, mscorlib]]
C#将数据转换为指定类型,支持对可空类型(Nullable类)转换方法示例
我们知道在C#中,引用类型可以为null,而值类型不可以为null,就是值类型必须要有值。msdn上面的解释是值类型没有足够的空量来表示空值,它的容量只够表示适合该类型的值,没有多余的容量。而数据库中(比如sqlserver)中,任何类型的值都是可以为null的,这就给我们在往数据库中插入值带来麻烦了,比如要往数据库中的int字段中插入一个null值,而C#在2.0之前,是不可能给一个int类型的变量赋于null的。
为了解决这个问题,C#引入了Nullable类,该类为值类型赋于null值提供了支持,如果我们要为一个int类型赋于null值,那么我们就可以声明该类型为Nullable<int >,也可以直接缩写为int?,这就是我们在C#2.0后版本中看到的大量可为空的值类型声明方式。
基础基元类型的概念:
可空类型的原类型称之为该类型的基础基元类型,比如我们声明了变量int?,那么我们就称int为int?的基础基元类型。
明白了这些概念后,现在假设我们要写一个方法,该方法要支持将一个object类型的值转换为任何可能转换的类型。
该类有两个参数,值value,类型convertsionType,
如果不支持可空类型,那么该方法很好实现,如下:
public static object ChanageType(object value, Type convertsionType)
{
return Convert.ChangeType(value, convertsionType);
}
{
return Convert.ChangeType(value, convertsionType);
}
但如果convertsionType为可空类型,该方法就会报类似如下错误了:
从“System.String”到“System.Nullable`1[[System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]”的强制转换无效。
所以改写方法如下:
public static class PageBaseHelper
{
public static object SD_ChanageType(this object value, Type convertsionType)
{
//判断convertsionType类型是否为泛型,因为nullable是泛型类,
if (convertsionType.IsGenericType &&
//判断convertsionType是否为nullable泛型类
convertsionType.GetGenericTypeDefinition().Equals(typeof(Nullable< >)))
{
if (value == null || value.ToString().Length == 0)
{
return null;
}
//如果convertsionType为nullable类,声明一个NullableConverter类,该类提供从Nullable类到基础基元类型的转换
NullableConverter nullableConverter = new NullableConverter(convertsionType);
//将convertsionType转换为nullable对的基础基元类型
convertsionType = nullableConverter.UnderlyingType;
}
return Convert.ChangeType(value, convertsionType);
}
}
{
public static object SD_ChanageType(this object value, Type convertsionType)
{
//判断convertsionType类型是否为泛型,因为nullable是泛型类,
if (convertsionType.IsGenericType &&
//判断convertsionType是否为nullable泛型类
convertsionType.GetGenericTypeDefinition().Equals(typeof(Nullable< >)))
{
if (value == null || value.ToString().Length == 0)
{
return null;
}
//如果convertsionType为nullable类,声明一个NullableConverter类,该类提供从Nullable类到基础基元类型的转换
NullableConverter nullableConverter = new NullableConverter(convertsionType);
//将convertsionType转换为nullable对的基础基元类型
convertsionType = nullableConverter.UnderlyingType;
}
return Convert.ChangeType(value, convertsionType);
}
}
OK,现在该方法可以适用于值对任何类型的转换了,试试吧!
其它參考:
利用反射给对象赋值
[.NET]將DataTable轉成List物件利用反射给对象赋值
Convert DataTable to List<T>
Convert to a Type on the fly in C#.NET
C#利用反射给对象赋值
如果该属性类型是未知非泛型类型,例如 int?
property.SetValue(obj,Convert.ChangeType(value, property.PropertyType), null);//类型转换。这时简单调用 ChangeType()方法,类型会报错。
沒有留言:
張貼留言