上一篇文章<利用泛型实现通用类型转换(反射TryParse方法)>,实现了一种利用泛型,通过判断泛型的类型,反射出TryParse方法,转换后返回泛型对应的类型对象的方法.
但是,实际工作中又发现了有些需求还是不能满足,比如本来就是用反射获取了对象的Properties,这时候要设置它的值的时候就出问题了,因为根本就不知道他的类型是什么,所以,对方又进行了些重构,加入一个重载,传入要转换类型的Type对象.这样就可以满足需求了.
代码如下:
//类型转换方法by:mcjiffy public static object ConvertType(object val,Type tp) { if(tp==null)throw new Exception("要转换的类型错误"); if (val == null) return null;//类型的默认值 //泛型Nullable判断,取其中的类型 if (tp.IsGenericType) { tp = tp.GetGenericArguments()[0]; } //string直接返回转换 if (tp.Name.ToLower() == "string") { return val.ToString(); } //反射获取TryParse方法 var TryParse = tp.GetMethod("TryParse", BindingFlags.Public | BindingFlags.Static, Type.DefaultBinder, new Type[] { typeof(string), tp.MakeByRefType() }, new ParameterModifier[] { new ParameterModifier(2) }); var parameters = new object[] { val, Activator.CreateInstance(tp) }; bool success = (bool)TryParse.Invoke(null, parameters); //成功返回转换后的值,否则返回类型的默认值 if (success) { return parameters[1]; } return tp.Assembly.CreateInstance(tp.FullName, false); }
通过代码可以发现,之前是通过泛型的typeof(T)得到要转换的类型,变为了参数的Type.这样在不知道要转换的类型是,但是可以通过一定受到得到这个Type的时候,可以传入进行类型转换.
之前的泛型类型转换即可改为:
public static T ConvertType <T>(object val,Type tp) { return (T)ConvertType(val,typeof(T)); }
应用场景:
class Program { static void Main(string[] args) { //数据源不一定是这样,可能是DataTable,QueryString等等 List<DictionaryEntry> list = new List<DictionaryEntry>(); list.Add(new DictionaryEntry("ID", "123")); list.Add(new DictionaryEntry("Name", "牛奶")); list.Add(new DictionaryEntry("Price", "20")); list.Add(new DictionaryEntry("Time", DateTime.Now.AddMonths(1).ToString())); PropertyInfo[] properties = typeof(Product).GetProperties(); Product product=new Product(); //这时候通过反射得到的属性,并不知道确切的类型 foreach (PropertyInfo p in properties) { //通过Dictionary中取出的值都是string DictionaryEntry entry = list.Find((x) => x.Key.ToString() == p.Name); //通过ProperyType可以得到一个类型的Type,传入到转换类型方法中 p.SetValue(product, Utilis.ConvertType(entry.Value, p.PropertyType), null); } Console.Write(product); Console.ReadKey(); } } class Product { public int ID { get; set; } public string Name { get; set; } public decimal Price { get; set; } public DateTime Time { get; set; } public override string ToString() { return string.Format("ID:{0},Name:{1},Price:{2},Time:{3}", this.ID.ToString(), this.Name, this.Price.ToString(), this.Time.ToShortDateString()); } }
点击 :149