Wednesday, April 23, 2014

KB: c#之反射

有时为了使相似度较高的代码智能化,我们会使用到反射。
这是Reflexion的命名空间using System.Reflection;

前面的blog说到C#之Entity framework,提到这段代码:

using (ModelEntities context = new ModelEntities())
{
     context.stocks_EF.Add(new stocks_EF() { Symbol = "CAT", Price = 98.42, PricePct = 2.5, Volume = 29389, AvgVolume = 39392, MktCap = "56.5B", Yield = 2.2, PE = 10.2, TradeDate = Convert.ToDateTime("2013-06-17 00:00:00.000") });
     context.SaveChanges();
}


    public partial class ModelEntities : DbContext
    {
        public DbSet<stocks_EF> stocks_EF { get; set; }

    }

下面我说说怎么用反射写这段代码。
1.已知道类型的Type:Type contextType = typeof(ModelEntities);如果是某instance的type是    
  obj.GetType()
2. 创建某类型的Instance:object context = Activator.CreateInstance(contextType);
3. 获得某Instance的某属性的值:
  object dbSetInstance = contextType.GetProperty(propName).GetValue(context);
4. 获得某Instance的某属性的类型:
    Type dbSetType = contextType.GetProperty(propName).PropertyType;
5.获得某类型的某方法:MethodInfo objAddMethod = dbSetType.GetMethod("Add");
6.Call某方法: objAddMethod.Invoke(dbSetInstance, new object[]{obj});
(eg2)7.获得泛型的参数类型
                if (propType.IsGenericType)
                {
                    Type[] paraList = propType.GetGenericArguments();
                    propertyName = paraList[0].Name;

                }
8.设置某属性的值:t.GetProperty(name).SetValue(obj, "abd")


Type contextType = typeof(ModelEntities);
object context = Activator.CreateInstance(contextType);
Type objType = obj.GetType();

var propNames = from p in contextType.GetProperties() select p.Name;

foreach (var propName in propNames)
{
    if (objType.ToString() == contextType.Namespace+"."+propName)
    {
         object dbSetInstance = contextType.GetProperty(propName).GetValue(context);
         Type dbSetType = contextType.GetProperty(propName).PropertyType;

         MethodInfo objAddMethod = dbSetType.GetMethod("Add");
         objAddMethod.Invoke(dbSetInstance, new object[] { obj });

         MethodInfo objSaveMethod = contextType.GetMethod("SaveChanges");
         objSaveMethod.Invoke(context, null);
     }
}

再训练一个:
    public partial class stocks_EF
    {
        public int ID { get; set; }
        public string Symbol { get; set; }
        public Nullable<double> Price { get; set; }
        public Nullable<double> PricePct { get; set; }
        public Nullable<int> Volume { get; set; }
        public Nullable<int> AvgVolume { get; set; }
        public string MktCap { get; set; }
        public Nullable<double> Yield { get; set; }
        public Nullable<double> PE { get; set; }
        public Nullable<System.DateTime> TradeDate { get; set; }
        public Nullable<System.DateTime> InsertTime { get; set; }

    }


code如下:
public static void Fill(string[] words, object obj)
{
    Type t = obj.GetType();
    var propNames = from p in t.GetProperties() select p.Name;
    int i=0;
    foreach (var name in propNames)
    {
        Type propType = t.GetProperty(name).PropertyType;
        string propertyName = propType.Name;

        if (propType.IsGenericType)
        {
            Type[] paraList = propType.GetGenericArguments();
            propertyName = paraList[0].Name;
        }
        if (propertyName == "DateTime")
            t.GetProperty(name).SetValue(obj, Convert.ToDateTime(words[i]));
        else if (propertyName == "Int32")
            t.GetProperty(name).SetValue(obj, Convert.ToInt32(words[i]));
        else if (propertyName == "Double")
            t.GetProperty(name).SetValue(obj, Convert.ToDouble(words[i]));
        else t.GetProperty(name).SetValue(obj, words[i]);
        i++;
    }


}

main函数:
string[] words = { "1", "CAT", "98.43", "2.5", "29389", "39392", "56.5B", "2.2", "10.2", "2013-06-17 00:00:00.000", "2014-04-23 00:00:00.000" };
 stocks_EF s = new stocks_EF();
 Fill(words, s);


No comments:

Post a Comment