C#反射使用场景之提高代码复用率

最近做项目时,用到了一点反射处理,下面简单聊一下什么是反射,及反射的使用场景,场景很重要,没有场景,很难深入了解一个技术点。反射是什么,这种在我看来比较高大上的概念就先不聊了,大家在网上搜索一下也很多,我们直接按照需求走一遍。

在ORM处理里,也就是数据库和Model关联时,假设Student表里有StudentID,SName,SClass字段,对应一个StuModel,具备同样的字段,我们怎么处理表和Model的映射关系呢。

※注:我们这里不连接真实的数据库了,用DataTable模拟数据库表。

下面的代码出现了。

Main处理:

using System;
using System.Collections.Generic;
using System.Data;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            Utils du = new Utils();
            DataTable dt = du.GetDBData();
            List<StuModel> lst = du.TableToStudent(dt);
            du.PrintStudent(lst);
            Console.Read();
        }
    }
}

Utils处理:

using System;
using System.Collections.Generic;
using System.Data;

namespace ConsoleApp1
{
    class Utils
    {
        public DataTable GetDBData()
        {
            DataTable dt = new DataTable();
            DataRow dr;
            dt.Columns.Add("StudentID");
            dt.Columns.Add("SName");
            dt.Columns.Add("SClass");

            for (int i = 0; i < 10; i++)
            {
                dr = dt.NewRow();
                dr["StudentID"] = (i + 1).ToString();
                dr["SName"] = i.ToString() + "AAA";
                dr["SClass"] = ((i + 1) % 7).ToString();
                dt.Rows.Add(dr);
            }
            return dt;
        }

        public List<StuModel> TableToStudent(DataTable dt)
        {
            List<StuModel> lst = new List<StuModel>();
            StuModel s;
            foreach (DataRow dr in dt.Rows)
            {
                s = new StuModel();
                s.StudentID = dr["StudentID"].ToString();
                s.SName = dr["SName"].ToString();
                s.SClass = dr["SClass"].ToString();
                lst.Add(s);
            }
            return lst;
        }

        public void PrintStudent(List<StuModel> lst)
        {
            foreach (StuModel m in lst)
            {
                Console.WriteLine(m.StudentID + ":" + m.SName + ":" + m.SClass);
            }
        }
    }
}

Model类:

namespace ConsoleApp1
{
    class StuModel
    {
        public string StudentID { get; set; }
        public string SName { get; set; }
        public string SClass { get; set; }
    }
}

貌似还可以,模块化了,代码也没有揉做一团。后来项目经理发话了,表加一个字段,SAge,码农们就动起来了,几乎时全盘改动,项目经理再加一个SGender,S。。。。,结局可能有两个,项目经理住院了,或者码农辞职了。。。

那么,能不能不让项目经理挨打,也别让员工辞职呢。有!

看下面一版写法:

Utils处理:

using System;
using System.Collections.Generic;
using System.Data;
using System.Reflection;

namespace ConsoleApp1
{
    class Utils
    {
        public DataTable GetDBData()
        {
            DataTable dt = new DataTable();
            DataRow dr;
            dt.Columns.Add("StudentID");
            dt.Columns.Add("SName");
            dt.Columns.Add("SClass");
            dt.Columns.Add("SAge");

            for (int i = 0; i < 10; i++)
            {
                dr = dt.NewRow();
                dr["StudentID"] = (i + 1).ToString();
                dr["SName"] = i.ToString() + "AAA";
                dr["SClass"] = ((i + 1) % 7).ToString();
                dr["SAge"] = i + 10;
                dt.Rows.Add(dr);
            }
            return dt;
        }

        public List<StuModel> TableToStudent(DataTable dt)
        {
            List<StuModel> lst = new List<StuModel>();
            StuModel s ;           
            foreach (DataRow dr in dt.Rows)
            {
                s = new StuModel();
                Type t = s.GetType();
                foreach (PropertyInfo p in t.GetProperties())
                {
                    p.SetValue(s, dr[p.Name].ToString());
                }
                lst.Add(s);
            }
            return lst;
        }

        public List<string> PrintStudent(List<StuModel> listStu)
        {
            string str;
            List<string> lst = new List<string>();
            foreach (StuModel m in listStu)
            {
                str = string.Empty;
                Type t = m.GetType();
                foreach (PropertyInfo p in t.GetProperties())
                {
                    str += p.GetValue(m) + ":";//为了简化代码,最后的:我们不处理了。
                }
                lst.Add(str);
            }
            return lst;
        }
    }
}

※注:StuModel里加一个SAge属性

public string SAge { get; set; }

按照这一版本写法,我们只需要保证Model和数据库的表字段完全一致就好了,我们把表数据转换成实体类之后的业务代码不用动,或者改动范围很小。减少改修时的规模和问题发生几率。

反射其中一个用途就是运行时动态获取对象信息,不用反射,大多时候我们也能完成需求,用反射的的目的是提高代码的复用率,在需求变更时不要全盘修改。


 

发布了51 篇原创文章 · 获赞 4 · 访问量 4242

猜你喜欢

转载自blog.csdn.net/songjian1104/article/details/100061316