上一篇文章<利用泛型实现通用类型转换(反射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