異世界


2012年7月14日 星期六

List<T> 的擴充方法

擴充方法讓您能將方法「加入」至現有型別,而不需要建立新的衍生型別 (Derived Type)、重新編譯,或是修改原始型別。 擴充方法是一種特殊的靜態方法,但是需將它們當成擴充型別上的執行個體方法 (Instance Method) 來呼叫。 對於以 C# 和 Visual Basic 撰寫的用戶端程式碼,呼叫擴充方法或是在型別中實際定義的方法,兩者之間並沒有明顯的差別。

擴充方法的第一個參數指定方法進行作業的型別,而這個參數的前面需加上 this 修飾詞 (Modifier)。 使用 using 指示詞,將命名空間 (Namespace) 明確匯入至原始程式碼時,擴充方法才會進入範圍中。

 

下列範例是 List<T> 的擴充方法,可以將List<T> 轉成XML存檔,或由XML檔載入到List<T>中。

範例已經做過局部修改,原始來源 :  MVC 閒暇實作 [將 List<T> 儲存為DataSet 的XML]

 

該擴充方法僅能使用轉換基本型態,若有套疊的List<T>或 [],無法轉換。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Data;
using System.Reflection;
using System.IO;
 
namespace nmsEventLog.Extension
{    
    /// <summary>
    /// 資訊來源:http://www.dotblogs.com.tw/gelis/archive/2012/04/15/71535.aspx
    /// </summary>
    /// 
    /// 擴充方法必須定義為靜態方法,但使用執行個體方法語法進行呼叫。 
    /// 擴充方法的第一個參數指定方法進行作業的型別,而這個參數的前面需加上 this 修飾詞 (Modifier)。 
    /// 使用 using 指示詞,將命名空間 (Namespace) 明確匯入至原始程式碼時,擴充方法才會進入範圍中。 
    /// 
    public static class ListExtensionMethod
    {
        /// <summary>
        /// 將 List<T> 轉換為 DataSet 並存為XML檔案.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="list"></param>
        public static int SaveToDisk<T>(this List<T> list, string XmlPath)
        { 
            int result = 0;
            DataTable dt = new DataTable();
            if (list.Count > 0)
            {
                Type obj = list.Take(1).Single().GetType();     //若有資料,
                PropertyInfo[] pInfo = obj.GetProperties();
                dt.TableName = obj.Name;
  
                foreach (PropertyInfo info in pInfo)
                {
                    if (info.MemberType == MemberTypes.Property)
                    {
                        dt.Columns.Add(new DataColumn(info.Name));
                    }
                }
            }
            else
                return result;
  
            foreach (var p in list)
            {
                PropertyInfo[] pPty = p.GetType().GetProperties();
  
                DataRow dr = dt.NewRow();
 
                foreach (PropertyInfo pp in pPty)
                {
                    if (pp.MemberType == MemberTypes.Property)
                    {        
                        dr[pp.Name] = pp.GetValue(p, null);
                    }
                }
                dt.Rows.Add(dr);
                result++;
            }
            dt.WriteXml(XmlPath);
  
            return result;
        }
  
        /// <summary>
        /// 從磁碟讀取 DataSet 的 XML 檔案.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="list"></param>
        public static List<T> LoadFromDisk<T>(this List<T> list, string XmlPath)
        {
            List<T> t = new List<T>();
  
            DataSet ds = new DataSet();
            ds.ReadXml(XmlPath);
            DataTable dt = ds.Tables["ATable"]; 
            //dt.ReadXml(XmlPath);
            foreach (DataRow dr in dt.Rows)
            {
                T p = Activator.CreateInstance<T>();
                foreach(DataColumn col in dt.Columns)
                {
                    Type pType = p.GetType();
                    PropertyInfo pInfo = pType.GetProperty(col.ColumnName);
                    if (pInfo.PropertyType == typeof(System.Int32))
                    {
                        pInfo.SetValue(p, Convert.ToInt32(dr[col.ColumnName]), null);
                    }
                    else
                    {
                        pInfo.SetValue(p, dr[col.ColumnName], null);
                    }
                }
                t.Add(p);
            }
            return t;
        }
  }
 
}


 


實際調用注意:
1. using nmsEventLog.Extension;
2. public void xmlLoadGroupList() { GroupList.LoadFromDisk(Path.Combine(xmlPath,"xGroupList.xml")); }



using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.ComponentModel;
using System.Net.NetworkInformation;
using System.Threading;
using System.Reflection;
using System.IO;
using System.Xml;
using nmsEventLog.Extension;
 
 
namespace NmsLogLog
{
    class nms
    {                
        /// <summary>
        /// 資料紀錄區
        /// </summary>
        #region < 資料紀錄區 >
        public List<NmsGroup> GroupList = new List<NmsGroup>();
        public List<NmsStation> StationList = new List<NmsStation>();
        public List<NmsDevice> DeviceList = new List<NmsDevice>();
        public List<NmsMessage> MsgList = new List<NmsMessage>();
        public List<NmsVar> VarList = new List<NmsVar>();
        public List<NmsLog> AlarmList = new List<NmsLog>();
        public List<NmsLog> HistoryList = new List<NmsLog>();
 
        #region <XmlDB Load & Save >
        private string sToday = DateTime.Today.ToString("yyy_MM_dd");
        public string xmlPath { get; set; }
        //..Load
        public void xmlLoadGroupList() { GroupList.LoadFromDisk(Path.Combine(xmlPath,"xGroupList.xml")); }
        public void xmlLoadStationList() { StationList.LoadFromDisk(Path.Combine(xmlPath, "xStationList.xml")); }
        public void xmlLoadDeviceList() { DeviceList.LoadFromDisk(Path.Combine(xmlPath, "xDeviceList.xml")); }
        public void xmlLoadMsgList() { MsgList.LoadFromDisk(Path.Combine(xmlPath, "xMsgList.xml")); }
        public void xmlLoadVarList() { VarList.LoadFromDisk(Path.Combine(xmlPath, "xNmsVar.xml")); }
        public void xmlLoadAlarmList() { AlarmList.LoadFromDisk(Path.Combine(xmlPath, "xAlarmList.xml")); }
        public void xmlLoadHistoryList() { HistoryList.LoadFromDisk(Path.Combine(xmlPath, string.Format("{0}_HistoryList", DateTime.Today.ToString()))); }
        //..Save
        public void xmlSaveGroupList() { GroupList.SaveToDisk(Path.Combine(xmlPath, "xGroupList.xml")); }
        public void xmlSaveStationList() { StationList.SaveToDisk(Path.Combine(xmlPath, "xStationList.xml")); }
        public void xmlSaveDeviceList() { DeviceList.SaveToDisk(Path.Combine(xmlPath, "xDeviceList.xml")); }
        public void xmlSaveMsgList() { MsgList.SaveToDisk(Path.Combine(xmlPath, "xMsgList.xml")); }
        public void xmlSaveVarList() { VarList.SaveToDisk(Path.Combine(xmlPath, "xNmsVar.xml")); }
        public void xmlSaveAlarmList() { AlarmList.SaveToDisk(Path.Combine(xmlPath, "Log", "xAlarmList.xml")); }
        public void xmlSaveHistoryList() { HistoryList.SaveToDisk(Path.Combine(xmlPath, "Log", string.Format("{0}_HistoryList.xml", sToday))); }
 
        #endregion // <XmlDB Load & Save >
        #endregion //< 資料紀錄區 >
    }
}

沒有留言:

張貼留言