注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

hurt0759的个人主页

人生常态--跋涉.人生暂态--歇息.

 
 
 

日志

 
 

C#2.0中通过反射功能给类赋值  

2009-09-07 16:55:01|  分类: IT |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

C#2.0中通过反射功能给类赋值,常见于数据库读取后的赋值操作

2008-02-29 14:59

在日程程序开发中,特别是与数据库打交道时,经常要给各种类型的数据赋值,类似与下面这种:

(由于代码是从一个项目中拿出的部分示例,可能不完整,不方便理解,但不防从中看到一种方法,

网上虽然有许多的数据持久化的东西,但作为程序员,总得自己不断尝试,不断完善.)

转载请注明出处:http://hi.baidu.com/ipress/

   if(dr[0] !=DBNull.Value)      product.ProductName       =dr.GetString(0);

    if(dr[1] !=DBNull.Value)      product.ProductCode       =dr.GetString(1);

    if(dr[2] !=DBNull.Value)      product.ProductMemo       =dr.GetString(2);

    if(dr[3] !=DBNull.Value)      product.ProductPrice      =dr.GetString(3);

    if(dr[4] !=DBNull.Value)      product.ServiceProvider   =dr.GetString(4);

    if(dr[5] !=DBNull.Value)      product.ProductAffirmURL =dr.GetString(5);

    if(dr[6] !=DBNull.Value)      product.ProductChargeTag =dr.GetString(6);

    if(dr[7] !=DBNull.Value)      product.ProductChargeURL =dr.GetString(7);

    if(dr[8] !=DBNull.Value)      product.CopyrightDeclare =dr.GetString(8);

    if(dr[9] !=DBNull.Value)      product.SkinID            =dr.GetInt32(9);

每个数据类型都要重复写类似的语句,非常麻烦枯燥,我们可以利用.NET的反射特性赋值,简化开发.

基类

public abstract class ItemData : IData

    {

        /// <summary>

        /// 数据绑定,通过反射动态给该类赋值

        /// </summary>

        /// <param name="_list"></param>

        public virtual void Bind(Property _list)

        {

            Type type = this.GetType();

            PropertyInfo[] plist = type.GetProperties();

            foreach (PropertyInfo info in plist)

            {

               object value = _list[info.Name];

                if ( value != null ){//有值则赋值

                    info.SetValue(this, value, null);

                }

            }//end for

        }

    }

转载请注明出处:http://hi.baidu.com/ipress/

Property类是个集合类,继承自System.Collections.Specialized.NameObjectCollectionBase

    public class Property : System.Collections.Specialized.NameObjectCollectionBase

    {

        /// <summary>

        /// 重写基类方法,当集合中有重复数据时,修改原有数据值,确保没有重复数据项.

        /// </summary>

        /// <param name="name">键名,为null时不会添加</param>

        /// <param name="value">键值,为null时不会添加</param>

        public void Add(string name, object value)

        {

            if (string.IsNullOrEmpty(name) || value == null) return;

            if (Get(name) == null)

            { //无具有该键值的项时,新增

                BaseAdd(name, value);

            }

            else

            {

                BaseSet(name, value);

            }

        }

        /// <summary>

        /// 获取键名

        /// </summary>

        public string[] AllKeys

        {

            get { return BaseGetAllKeys(); }

        }

        /// <summary>

        /// 移除指定键名的项

        /// </summary>

        /// <param name="name"></param>

        public void Remove(string name)

        {

            BaseRemove(name);

        }

        /// <summary>

        /// 移除指定位置的项

        /// </summary>

        /// <param name="index"></param>

        public void RemoveAt(int index)

        {

            BaseRemoveAt(index);

        }

        public object this[int index]

        {

            get { return Get(index); }

        }

        public object this[string name]

        {

            get { return Get(name); }

        }

        /// <summary>

        /// 通过键名获取键值

        /// </summary>

        /// <param name="name"></param>

        /// <returns></returns>

        public object Get(string name)

        {

            return BaseGet(name);

        }

        /// <summary>

        /// 通过索引获取某个值

        /// </summary>

        /// <param name="index"></param>

        /// <returns></returns>

        public object Get(int index)

        {

            return BaseGet(index);

        }

        /// <summary>

        /// 设置某个项的值

        /// </summary>

        /// <param name="name">名</param>

        /// <param name="value">值</param>

        public void Set(string name, object value)

        {

            Add(name, value);

        }

        /// <summary>

        /// 清除所以键及值

        /// </summary>

        public void Clear()

        {

            BaseClear();

        }

    }

转载请注明出处:http://hi.baidu.com/ipress/

这样,我们的数据类型只需要继承自ItemData 类,就可以通过以下方式,自动赋值.

/// <summary>

        /// 处理实现IData接口的数据

        /// </summary>

        /// <param name="type"></param>

        /// <param name="reader"></param>

        private static IData GetItem(Type type, IDataReader reader)

        {

            IData _date = (IData)System.Activator.CreateInstance(type);

            GetItem(_date, reader);

            return _date;

        }

private static void GetItem(IData item, IDataReader reader)

        {

            if (reader.Read()){

                item.Bind(GetElement(reader));

            }

            else{

                item = null;

            }

        }

private static Property GetElement(IDataReader reader)

        {

            Property collection = new Property();

            for (int i = 0; i < reader.FieldCount; i++){

                if(reader[i] != DBNull.Value) collection.Add(reader.GetName(i), reader[i]);

            }

            return collection;

        }

这样繁琐的操作就简单得多了.我们甚至还可以在伸入开发出更简洁的方式.

同样,对于某个类型的列表,也可以以类似的方式操作.先定义一个基类.

public class ItemDataList : IDataList

    {

        #region 变量及属性

        private System.Collections.IList _array = new System.Collections.ArrayList();

        private int _recordcount;

        private Type itemtype;

        /// <summary>

        /// 列表中集合的类型

        /// </summary>

        public Type ItemType

        {

            get { return itemtype; }

            set { itemtype = value; }

        }

        /// <summary>

        /// 实现IData接口的数据项集合.

        /// </summary>

        public System.Collections.IList Items{

            get { return _array; }

        }

        /// <summary>

        /// 记录总数

        /// </summary>

        public int RecordCount

        {

            get { return _recordcount; }

            set { _recordcount = value; }

        }

        #endregion

        public ItemDataList() { }

        /// <summary>

        /// 构造列表项

        /// </summary>

        /// <param name="type">子项的类型</param>

        public ItemDataList(Type type)

        {

            itemtype = type;

        }

        /// <summary>

        /// 数据绑定,调用该方法前,必须先指定ItemType的类型,否则此方法不做任何操作

        /// </summary>

        /// <param name="_list"></param>

        public virtual void Bind(System.Collections.IList _list)

        {

            if (ItemType != null)

            {

                foreach (Property l in _list)

                {

                    IData item = (IData)System.Activator.CreateInstance(ItemType);

                    if (item != null){

                        item.Bind(l);

                        _array.Add(item);

                    }

                }

            }

        }

    }

/// <summary>

        /// 处理实现IdataList接口的数据

        /// </summary>

        /// <param name="_dl"></param>

        /// <param name="reader"></param>

        private static void GetItemList(IDataList _dl, IDataReader reader)

        {

            IList _list = new ArrayList();

            while (reader.Read())

                _list.Add(GetElement(reader));

            if (reader.NextResult()){//记录总数

                if (reader.Read()){

                    if (reader[0] != DBNull.Value) _dl.RecordCount = reader.GetInt32(0);

                }

            }

            _dl.Bind(_list);

        }

/// <summary>

        /// 实例指定的类型,填充数据后并返回,Type必须是支持IData接口的数据

        /// </summary>

        /// <param name="type">Type</param>

        /// <param name="reader">IDataReader</param>

        /// <returns></returns>

        private static IDataList GetItemList(Type type, IDataReader reader)

        {

            IDataList _list = new ItemDataList(type);

            GetItemList(_list, reader);

            return _list;

        }

 

  评论这张
 
阅读(1226)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017