【ZT】利用反射排序泛型List

 
http://xianqiang.blog.163.com/blog/static/45268171200981110488644/

泛型集合List<T>类型转换

 

 

List<int> ints = new List<int>();

ints.Add(1);

ints.Add(10);

ints.Add(42);

List<object> objects = new List<object>();

方法一:

参考地址:http://msdn.microsoft.com/zh-cn/library/ms228359(VS.80).aspx

        public static void Add<S, D>(List<S> source, List<D> destination) where S : D
        {
            foreach (S sourceElement in source)
            {
                destination.Add(sourceElement);
            }
        }

       VarianceWorkaround.Add<int, object>(ints, objects);

 

方法二:参考MSDN的List<T>成员函数ConvertAll<TOutput>

       先看下泛型委托

public delegate void Del<T>(T item);

public static void Notify(int i) { }

Del<int> m1 = new Del<int>(Notify);

C# 2.0 版具有称为方法组转换的新功能,此功能适用于具体委托类型和泛型委托类型,并使您可以使用如下简化的语法写入上一行:

Del<int> m2 = Notify;

说了泛型委托后,言归正传,先定义一个类型转换方法

public static object intToObj(int item)

{//负责把 int 转换成 object 的函数

        return  (object) item ;
       }

就可以直接用ConvertAll<TOutput>方法了

list<object> obj = ints.ConvertAll( new Converter<int,object> (intToObj)  )

这样就ok了,完成List<T>的类型转换了

其中  ConvertAll<TOutput>方法是将当前 List<T> 中的元素转换为另一种类型,并返回包含转换后的元素的列表。 方法定义如下:

public List<TOutput> ConvertAll<TOutput>( Converter<T, TOutput> converter)

下面是这个ConvertAll<TOutput>方法用到的委托

public delegate TOutput Converter<TInput, TOutput>( TInput input)

 

 


 

泛型的总结
泛型最常见的用途是泛型集合,命名空间System.Collections.Generic 中包含了一些基于泛型的集合类,使用泛型集合类可以提供更高的类型安全性,还有更高的性能,避免了非泛型集合的重复的装箱和拆箱。
    很多非泛型集合类都有对应的泛型集合类,下面是常用的非泛型集合类以及对应的泛型集合类:
非泛型集合类 泛型集合类
ArrayList List<T>
HashTable DIctionary<T>
Queue Queue<T>
Stack Stack<T>
SortedList SortedList<T>


    我们用的比较多的非泛型集合类主要有 ArrayList类 和 HashTable类。我们经常用HashTable 来存储将要写入到数据库或者返回的信息,在这之间要不断的进行类型的转化,增加了系统装箱和拆箱的负担,如果我们操纵的数据类型相对确定的化  用 Dictionary<TKey,TValue> 集合类来存储数据就方便多了,例如我们需要在电子商务网站中存储用户的购物车信息( 商品名,对应的商品个数)时,完全可以用 Dictionary<string, int> 来存储购物车信息,而不需要任何的类型转化。

List类
注意:此类在 .NET Framework 2.0 版中是新增的。表示可通过索引访问的对象的强类型列表。提供用于对列表进行搜索、排序和操作的方法。命名空间: System.Collections.Generic,程序集:mscorlib(在 mscorlib.dll 中),List 类是 ArrayList 类的泛型等效类。

  //声明一个泛型类 
    class TestGenericList
    ...{
        static void Main()
        ...{
            //声明一个List对象,只加入string参数
            List<string> names = new List<string>();
            names.Add("乔峰");
            names.Add("欧阳峰");
            names.Add("马蜂");
            //遍历List
            foreach (string name in names)
            ...{
                Console.WriteLine(name);
            }
            //向List中插入元素
            names.Insert(2, "张三峰");
            //移除指定元素
            names.Remove("马蜂");         
        }
    }
在决定使用 List 还是使用 ArrayList 类(两者具有类似的功能)时,记住 List 类在大多数情况下执行得更好并且是类型安全的。如果对 List 类的类型 T 使用引用类型,则两个类的行为是完全相同的。但是,如果对类型 T 使用值类型,则需要考虑实现和装箱问题。

如果对类型 T 使用值类型,则编译器将特别针对该值类型生成 List 类的实现。这意味着不必对 List 对象的列表元素进行装箱就可以使用该元素,并且在创建大约 500 个列表元素之后,不对列表元素装箱所节省的内存将大于生成该类实现所使用的内存。

其实我们也可以自己定义一个泛型类,如下所示:
  //声明一个泛型类
    public class ItemList<T>
    ...{
        void Add(T item) ...{ }
    }
    class TestGenericList
    ...{
        private class ExampleClass ...{ }
        static void Main()
        ...{
            // 声明一个对象,只能加入int型
            ItemList<int> list1 = new ItemList<int>();

            //声明一个对象,只能加入Student类型,Student类为自定义类
            ItemList<Student> list2 = new ItemList<Student>();

        }
    }

泛型的用法还有很多种,如泛型方法,泛型委托,泛型接口等。



List 和 IList的区别 IList <Class1> IList11 =new List <Class1>();
List <Class1> List11 =new List <Class1>();

这两行代码,从操作上来看,实际上都是创建了一个List<Class1>对象的实例,也就是说,他们的操作没有区别。

只是用于保存这个操作的返回值变量类型不一样而已。

那么,我们可以这么理解,这两行代码的目的不一样。
List <Class1> List11 =new List <Class1>();
是想创建一个List<Class1>,而且需要使用到List<T>的功能,进行相关操作。

IList <Class1> IList11 =new List <Class1>();
只是想创建一个基于接口IList<Class1>的对象的实例,只是这个接口是由List<T>实现的。
所以它只是希望使用到IList<T>接口规定的功能而已。
C#里List的用法
主程序代码:



Code
static void Main(string[] args)
        {
            ClassList listClass = new ClassList();
            Console.WriteLine("请输入第个字符串");
            string a = Console.ReadLine();
            Console.WriteLine("请输入第二个字符串");
            string b = Console.ReadLine();

            foreach (string n in listClass.strList(a, b))
            {
                Console.WriteLine(n);
            }
类:
class ClassList
    {
        public List<string> strList(string str1,string str2)
        {
            string stra = str1 + str2;
            string strb = str2 + str1;
            string strc = str1 + str1;
            List<string> listStr = new List<string>();
            listStr.Add(stra);
            listStr.Add(strb);
            listStr.Add(strc);
            return listStr;
        }
    }




Code
public class Person
    {
      private string _name;
      private string _like;
      public string Name
      {
          get
          {
              return this._name;
          }
          set
          {
              this._name = value;
          }
      }
      public string Like
      {
          get
          {
              return this._like;
          }
          set
          {
              this._like = value;
          }
      }
    }
IList<Person> myPerson = new List<Person>();
            Person person = new Person();
            person.Like = "pingpong";
            person.Name = "panjun";
            myPerson.Add(person);
            foreach (Person person1 in myPerson)
            {
                this.label1.Text += person1.Name + person1.Like;
            }


Dictionary
此类在 .NET Framework 2.0 版中是新增的。表示键和值的集合。命名空间:System.Collections.Generic,程序集:mscorlib(在 mscorlib.dll 中)
    class TestGenericList
    ...{
        static void Main()
        ...{
//声明对象,参数表示,键是int类型,值是string类型
            Dictionary<int, string> fruit = new Dictionary<int, string>();
            try...{
            //加入重复键会引发异常
                fruit.Add(1, "苹果");
                fruit.Add(2, "桔子");
                fruit.Add(3, "香蕉");
                fruit.Add(4, "菠萝");           
  //参数错误将引发异常,如下所示
  //fruit.Add("5", "aa");
            }
            catch (ArgumentException)
            ...{
                Console.WriteLine("添加错误!!!");
            }
//因为引入了泛型,所以键取出后不需要进行Object到int的转换,值的集合也一样
            foreach (int i in fruit.Keys)
            ...{
                Console.WriteLine("键是:{0}  值是:{1}",i,fruit);
            }
      //删除指定键,值
            fruit.Remove(1);
            //判断是否包含指定键
            if (fruit.ContainsKey(1))
            ...{
                Console.WriteLine("包含此键");
            }
            //清除集合中所有对象
            fruit.Clear();
        }
    }
Dictionary遍历输出的顺序,就是加入的顺序,这点与Hashtable不同,其它方法如:ContainsKey ,ContainsValue ,Remove 等,使用方法基本一致。

======================================================================================
.NET(C#) Hashtable Dictionary 探索
先看下面的代码

using System;
using System.Collections;

namespace NoSortHashtable
{
    /// <summary>
    /// Summary description for Class1.
    /// </summary>
    class Class1
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
       
        static void Main(string[] args)
        {
            Hashtable hashTable = new Hashtable();

            hashTable.Add("hunan","changsha");
            hashTable.Add("beijing","beijing");
            hashTable.Add("anhui","hefei");
            hashTable.Add("sichuan","chengdu");
            foreach(string str in hashTable.Keys)
            {
                Console.WriteLine(str + " : " + hashTable);
            }

        }
    }
}

打印的结果是:
    anhui : hefei
    hunan : changsha
    sichuan : chengdu
    beijing : beijing
为何产生这样的结果? 我查了MSDN后发现 ----------------------------------------------------------------------------------------------------Hashtable 对象由包含集合元素的存储桶组成。存储桶是 Hashtable 中各元素的虚拟子组,与大多数集合中进行的搜索和检索相比,存储桶可令搜索和检索更为便捷。每一存储桶都与一个哈希代码关联,该哈希代码是使用哈希函数生 成的并基于该元素的键。

哈希函数是基于键返回数值哈希代码的算法。键是正被存储的对象的某一属性的值。哈希函数必须始终为相同的键返回相同的哈希代码。一个哈希函数能够为两个不同的键生成相同的哈希代码,但从哈希表检索元素时,为每一唯一键生成唯一哈希代码的哈希函数将令性能更佳。

在 Hashtable 中用作元素的每一对象必须能够使用 GetHashCode 方法的实现为其自身生成哈希代码。但是,还可以通过使用接受 IHashCodeProvider 实现作为参数之一的 Hashtable 构造函数,为 Hashtable 中的所有元素指定一个哈希函数。

在将一个对象添加到 Hashtable 时,它被存储在存储桶中,该存储桶与匹配该对象的哈希代码的哈希代码关联。在 Hashtable 内搜索一个值时,将为该值生成哈希代码,并且搜索与该哈希代码关联的存储桶。

例如,一个字符串的哈希函数可以采用该字符串中每一字符的 ASCII 代码并它们添加到一起来生成一个哈希代码。字符串“picnic”将具有与字符串“basket”的哈希代码不同的哈希代码;因此,字符串 “picnic”和“basket”将处于不同的存储桶中。与之相比,“stressed”和“desserts”将具有相同的哈希代码并将处于相同的存 储桶中。

Dictionary 类与 Hashtable 类的功能相同。对于值类型,特定类型(不包括 Object)的 Dictionary 的性能优于 Hashtable,这是因为 Hashtable 的元素属于 Object 类型,所以在存储或检索值类型时通常发生装箱和取消装箱操作。

----------------------------------------------------------------------------------------------------
产生这个结果的原因就是Hashtable内部的排序机制使然,但我现在就是不想排序,我按什么顺序输入的,就想它再怎么给我输出,怎么办?google 后发现几个可以解决的办法,不过都需要自己写代码实现比如,继承hashtable,使用不自动排序的arraylist做中间桥
using System;
using System.Collections;

namespace NoSortHashtable
{
    public class NoSortHashtable : Hashtable
  {
        private ArrayList keys = new ArrayList();

        public NoSortHashtable()
        {
        }

        public override void Add(object key, object value)
        {
            base.Add (key, value);
            keys.Add (key);
        }

        public override ICollection Keys
        {
            get
            {
                return keys;
            }
        }

        public override void Clear()
        {
            base.Clear ();
            keys.Clear ();
        }

        public override void Remove(object key)
        {
            base.Remove (key);
            keys.Remove (key);
        }
        public override IDictionaryEnumerator GetEnumerator()
        {
            return base.GetEnumerator ();
        }

    }
}
或者只要Compare函数的返回结果不等于0就可以添加相同的Key,这样可以实现既可以排序,又可以有相同的Key值,可能在某些情况下会用得到。 using System;
using System.Collections;

namespace testSortedList
{
    class Class1
    {
       
        static void Main(string[] args)
        {
            SortedList sl = new SortedList(new MySort());        //不排序
            sl.Add(333,333);
            sl.Add(111,111);
            sl.Add(222,222);
            sl.Add(111,112);

            PrintList(sl);

            Console.ReadLine();
        }

        private static void PrintList(SortedList sl)
        {
            for(int i=0;i<sl.Count ;i++)
            {
                Console.WriteLine("{0}\t{1}",sl.GetKey(i),sl.GetByIndex(i));
            }//end for
        }//end fn()

    }
    public class MySort:IComparer
    {
        #region IComparer 成员
        public int Compare(object x, object y)
        {
            return -1;

            //排序
//            int iResult = (int)x - (int)y;
//            if(iResult == 0) iResult = -1;
//            return iResult;

        }
        #endregion
    }

}



使用单链接列表实现 IDictionary。建议用于通常包含 10 个或 10 个以下项的集合。


最后我测试了使用泛类型的Dictionary<T,T>, 尽管msdn上说hashtable和Dictionary的实现是一样的,不过同样的数据,返回的结果却是不同的,我没有找到更多的解释,测试代码如下


using System;
using System.Collections;
using System.Collections.Specialized;
using System.Collections.Generic;

namespace NoSortHashtable
{
    /// <summary>
    /// Summary description for Class1.
    /// </summary>
    public class Class1
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
       
        static void Main(string[] args)
        {
            Hashtable ht = new Hashtable();
            ht.Add("hunan","changsha");
            ht.Add("beijing","beijing");
            ht.Add("anhui","hefei");
            ht.Add("sichuan","chengdu");
            foreach(string str in ht.Keys)
            {
                Console.WriteLine(str + " : " + ht);
            }   
           
            Console.WriteLine("------------------------------------");
             
            Dictionary<String,String> dic = new Dictionary<String,String>();
            dic.Add("hunan","changsha");
            dic.Add("beijing","beijing");
            dic.Add("anhui","hefei");
            dic.Add("sichuan","chengdu");
            foreach(string str in dic.Keys)
            {
                Console.WriteLine(str + " : " + dic);
            }
           
            Console.WriteLine("------------------------------------");
             
            ListDictionary lsdic = new ListDictionary();
            lsdic.Add("hunan","changsha");
            lsdic.Add("beijing","beijing");
            lsdic.Add("anhui","hefei");
            lsdic.Add("sichuan","chengdu");
            foreach(string str in lsdic.Keys)
            {
                Console.WriteLine(str + " : " + lsdic);
            }
        }
  }
}

另外,System.Collections.Specialized.ListDictionary也是可以完成该要求的,不过。。。
========================================================================================
3個對泛型 List 排序的方法

方式1:


    List<SoftDrink> list = manager.SoftDrink.ListSoftDrink();
    list.Sort(new MyComp().Compare);
    list.Sort(new MyCompDesc().Compare);


        public class MyComp : IComparer<SoftDrink> {
            public int Compare(SoftDrink x, SoftDrink y) {
                return String.Compare(x.SerialId, y.SerialId);
            }
        }

        public class MyCompDesc : IComparer<SoftDrink> {
            public int Compare(SoftDrink x, SoftDrink y) {
                return String.Compare(y.SerialId, x.SerialId);
            }
        }




方式2:


list.Sort(
    new Comparison<SoftDrink>(
        delegate(SoftDrink x, SoftDrink y) {
            return String.Compare(x.SerialId, y.SerialId);
        }));
list.Sort(
    new Comparison<SoftDrink>(
        delegate(SoftDrink x, SoftDrink y) {
            return String.Compare(y.SerialId, x.SerialId);
        }));




方式3: 使用 Dynamic Reflection Library


DynamicComparer<SoftDrink> comparer = new DynamicComparer<SoftDrink>("SerialId");
DynamicComparer<SoftDrink> comparerDesc = new DynamicComparer<SoftDrink>("SerialId DESC");
list.Sort(comparer);
list.Sort(comparerDesc);




在List有90筆 SoftDrink的情況下,對List正排倒排連續做1000次

方法1: 0.424 秒
方法2: 0.393 秒
方法3: 1.859 秒
方法3: 0.527 秒 (如果new Comparer()放在迴圈外)



不要覺得 Dynamic Reflection Library 慢就沒用呀,他能容易的對多屬性做排序,而速度差異也不大
比較糟的是,如果我的物件裏有子物件,我要對依子物件的屬性做排序,他就辦不到了。

 



 

http://blog.csdn.net/cxb_wind/archive/2008/04/10/2277670.aspx

C#中List用法

How to find objects in Generics with List.Find() method

I've been looking for help on how to find objects in Generics with List.Find() method .... and ... take a look what I have found.
In the follow example, I created a simple class:

public class Person
{
       private int _id;
       private string _name;

       public int ID {  get{ return _id;} set{ _id = value;}}
       public int Name {  get{ return _name;} set{ _name= value;}}

       public Person(int id, string name)
       {
             _id = id;
             _name = name;
       }
}

In the example, there's a simple class with two private attributes. Now we're going to create a typed List of this object and take advantage of the Find() method

public void CreateAndSearchList()
{
      //create and fill the collection
      List<Person> myList = new List<Person>();
      myList.Add(new Person(1, "AndreySanches"));
      myList.Add(new Person(2, "AlexandreTarifa"));
      myList.Add(new Person(3, "EmersonFacunte"));

     //find a specific object
     Person myLocatedObject = myList.Find(delegate(Person p) {return p.ID == 1; });
}

备注:在list和array集合中搜索元素经常使用该方法,主要技术是泛型委托

list用法注意:如果增加一个对象,必须重新new一个对象,看下面的例子:


person p=new pewson();
for(int i=0;i<5;i++)
{
 p.ID=i;
 p.Name="xxxx";
 list.add(p);
}

for(int i=0;i<5;i++)
{
 person p=new person();
 p.ID=i;
 p.Name="xxxx";
 list.add(p);
}

上面有区别吗?在输出list的值是有区别了,第一个list里面存放的都是一样的,结果和最后一个一样,都是同一个人对象,第二个list达到预 期的效果,存储不同的人对象。这是为什么?原因很简单,一个list对象中存储的都是对一个共有的对象进行引用,所以以最后改变的值为准。

对象的排序:本文主要阐述对存储datatable的list进行按TableName排序

1、新建一个sort类

 public class SceneSort:IComparer<DataTable>
    {
       public int Compare(DataTable obj1, DataTable obj2)
       {
           int tableNameLength1;
           int tableNameLength2;
           if (obj1 == null)
           {
               if (obj2 == null)
                   return 0;
               else
                   return -1;
           }
           else
           {
               if (obj2 == null)
                   return 1;
               else
               {
                   tableNameLength1=obj1.TableName.Length;
                   tableNameLength2=obj2.TableName.Length;
                   if (Convert.ToInt32(obj1.TableName.Substring(2,tableNameLength1-2))>Convert.ToInt32(obj2.TableName.Substring(2,tableNameLength2-2)))
                       return 1;                            //大于返回1
                   else if (Convert.ToInt32(obj1.TableName.Substring(2,tableNameLength1-2))<Convert.ToInt32(obj2.TableName.Substring(2,tableNameLength2-2)))
                       return -1;                           //小于返回-1
                   else
                       return 0;                            //相等返回0
               }
           }

       }
2 排序:
List<DataTable> ldt = new List<DataTable>();
SceneSort ss=new SceneSort ();
tablelist.sort(ss);即可对list进行排序;

 

 


 

 

http://www.cnblogs.com/dytes/archive/2009/01/06/1370623.html

 

 

 

在最近一个项目中,有需求要对页面中所有的gridview 添加排序功能。由于gridview 的数据源绑定的是一个集合类List ,而不是DataTable ,所以无法使用DataView 排序功能。另外,不同的gridview 显示的是不同的业务数据,为了重用代码只能添加一个泛型方法,使用该方法对数据类型T ,按照任意给定的属性进行排序。由于是要按照某个不固定的属性对List 内的对象进行排序,所以修改类型T ,使之实现IComparable 接口,并利用List 类的Sort () 方法进行排序是无法满足需求的。但是List 类还提供了另一个Sort 方法,它接受一个IComparer 对象作为参数,在IComparer 内可以实现排序的业务逻辑。唯一需要的就是进行排序的属性了,而这个在程序的上下文是已知的。

  思路已经有了,但动手写代码前,google了一下相关文章,竟然发现有一段功能类似的代码,唯一不同是该该代码的实现中方法并不是泛型的。但是强大的地方是,代码中对实现的排序支持按照多个属性排序。于是稍加修改,一段强大的支持按照多属性对List进行排序的泛型方法就出炉了。

  首先是表示排序属性和排序方向的类SortClass,其中保存了排序的属性和排序的方向。

 

ExpandedBlockStart.gif 代码1
     ///   <summary>
    
///  Class used to hold sort information
    
///   </summary>
     public   class  SortClass
    {
        
private   string  _sortProperty;

        
public   string  SortProperty
        {
            
get  {  return  _sortProperty; }
            
set  { _sortProperty  =  value; }
        }
        
private  SortDirection _sortDirection;

        
public  SortDirection SortDirection
        {
            
get  {  return  _sortDirection; }
            
set  { _sortDirection  =  value; }
        }

        
public  SortClass( string  sortProperty, SortDirection sortDirection)
        {
            _sortProperty 
=  sortProperty;
            _sortDirection 
=  sortDirection;
        }


 

有了 SortClass后就可以开始实现IComparar接口了。下面是Comparer的代码,它实现了IComparar接口,包含实际的排序功能。从代码中可以看出,Comparer通过递归调用CheckSort方法来首先按照多个属性排序的。

 

ExpandedBlockStart.gif 代码2
  ///   <summary>
    
///  Implementation of IComparer
    
///   </summary>
     public   class  Comparer < T >  : IComparer < T >
    {
        
private  List < SortClass >  _sortClasses;

        
///   <summary>
        
///  Collection of sorting criteria
        
///   </summary>
         public  List < SortClass >  SortClasses
        {
            
get  {  return  _sortClasses; }
        }

        
///   <summary>
        
///  Default Constructor
        
///   </summary>
         public  Comparer()
        {
            _sortClasses 
=   new  List < SortClass > ();
        }

        
///   <summary>
        
///  Constructor that takes a sorting class collection as param
        
///   </summary>
        
///   <param name="sortClass">
        
///  Collection of sorting criteria 
        
/// </param>
         public  Comparer(List < SortClass >  sortClass)
        {
            _sortClasses 
=  sortClass;
        }

        
///   <summary>
        
///  Constructor 
        
///   </summary>
        
///   <param name="sortProperty"> Property to sort on </param>
        
///   <param name="sortDirection"> Direction to sort </param>
         public  Comparer( string  sortProperty, SortDirection sortDirection)
        {
            _sortClasses 
=   new  List < SortClass > ();
            _sortClasses.Add(
new  SortClass(sortProperty, sortDirection));
        }

        
///   <summary>
        
///  Implementation of IComparer interface to compare to object
        
///   </summary>
        
///   <param name="x"></param>
        
///   <param name="y"></param>
        
///   <returns></returns>
         public   int  Compare(T x, T y)
        {
            
if  (SortClasses.Count  ==   0 )
            {
                
return   0 ;
            }
            
return  CheckSort( 0 , x, y);
        }

        
///   <summary>
        
///  Recursive function to do sorting
        
///   </summary>
        
///   <param name="sortLevel"> Current level sorting at </param>
        
///   <param name="myObject1"></param>
        
///   <param name="myObject2"></param>
        
///   <returns></returns>
         private   int  CheckSort( int  sortLevel, T myObject1, T myObject2)
        {
            
int  returnVal  =   0 ;
            
if  (SortClasses.Count  -   1   >=  sortLevel)
            {
                
object  valueOf1  =  myObject1.GetType().GetProperty(SortClasses[sortLevel].SortProperty).GetValue(myObject1,  null );
                
object  valueOf2  =  myObject2.GetType().GetProperty(SortClasses[sortLevel].SortProperty).GetValue(myObject2,  null );
                
if  (SortClasses[sortLevel].SortDirection  ==  SortDirection.Ascending)
                {
                    returnVal 
=  ((IComparable)valueOf1).CompareTo((IComparable)valueOf2);
                }
                
else
                {
                    returnVal 
=  ((IComparable)valueOf2).CompareTo((IComparable)valueOf1);
                }

                
if  (returnVal  ==   0 )
                {
                    returnVal 
=  CheckSort(sortLevel  +   1 , myObject1, myObject2);
                }
            }


            
return  returnVal;
        }
    }


 

准备工作完成后,就可以开始实现真正强大的泛型排序方法了。 ListSorter提供了2个静态方法,一个用来对多个属性排序,另一个为了方便只针对一个属性进行排序的情况。

 

ExpandedBlockStart.gif 代码3
public   class  ListSorter
    {
        
public   static  List < T >  SortList < T > (List < T >  listToSort, 
                                       List
< string >  sortExpression, 
                                       List
< SortDirection >  sortDirection)
        {
            
// check parameters           
             if  (sortExpression.Count  !=  sortDirection.Count ||
                sortExpression.Count
== 0 ||
                sortDirection.Count
== 0 )
            {
                
throw   new  Exception( " Invalid sort arguments! " );
            }

            
// get myComparer
            Comparer < T >  myComparer  =   new  Comparer < T > ();
            
for  ( int  i  =   0 ; i  <  sortExpression.Count; i ++ )
            {
                SortClass sortClass 
=   new  SortClass(sortExpression[i], sortDirection[i]);
                myComparer.SortClasses.Add(sortClass);
            }

             listToSort.Sort(myComparer);
             
return  listToSort;

        }

        
public   static  List < T >  SortList < T > (List < T >  listToSort, 
                                       
string  sortExpression, 
                                       SortDirection sortDirection)
        {
            
// check parameters
             if  (sortExpression  ==   null   ||  sortExpression  ==   string .Empty  ||
                sortDirection 
==   null )
            {
                
return  listToSort;
            }

            Comparer
< T >  myComparer  =   new  Comparer < T > ();
            myComparer.SortClasses.Add(
new  SortClass(sortExpression, sortDirection));
            listToSort.Sort(myComparer);
            
return  listToSort;
        }
    }

有了上面的代码,只需简单几行就可以轻松实现对泛型List的排序功能了:


List < Project >  projectList = ..

            List
< Project >  sortedProject  =

                        ListSorter.SortList(projectList, 
" Name " , SortDirection.Ascending);


 

 



另外一个简单点的例子

 

http://news.cnblogs.com/q/15266/
ExpandedBlockStart.gif 代码
private  List < T >  TableToList < T > (T obj, DataTable tt)
        {
            System.Type type 
=  obj.GetType();
            List
< T >  list  =   new  List < T > ();
            
for  ( int  i  =   0 ; i  <  tt.Rows.Count; i ++ )
            {
                T item 
=  (T)Activator.CreateInstance(type);

                
object  value;

                
foreach  (DataColumn c  in  tt.Columns)
                {
                    value 
=  tt.Rows[i][c];
                    
if  (value  !=  System.DBNull.Value)
                    {
                        type.GetProperty(c.ColumnName).SetValue(item, tt.Rows[i][c], 
null );
                    }
                }

                list.Add(item);
            }
            
return  list;
        }

1.  System.Type type = obj.GetType(); 获取类型信息,例如,你想把DataTable最后转换为List<Product>,那么这里的T 的Type就是Product.

 

2. List<T> list = new List<T>(); 定义你要返回的列表,如上面提到的
List<Product>,因为DataTable的每一行的数据就可以填充一个对象,DataTable所有的数据当然就得返回为List了。

 

3 .  T item = (T)Activator.CreateInstance(type); 根据之前获取的类型信息创建一个实例,你在程序中用的肯定就是对象的实例。

 

4..

  object value;

                foreach (DataColumn c in tt.Columns)
                {
                    value = tt.Rows[i][c];
                    if (value != System.DBNull.Value)
                    {
                        type.GetProperty(c.ColumnName).SetValue(item, tt.Rows[i][c], null);
                    }
                }

 

看到 type.GetProperty(c.ColumnName).SetValue(item, tt.Rows[i][c], null);分解如下:

type.GetProperty(c.ColumnName)(通过属性的名字) 获取之前创建的那个实例的属性的信息,注意:你的实体类的的属性名必须和数据库中表的列名一样。

SetValue(item, tt.Rows[i][c], null); 给属性赋值

OK


 

转载于:https://www.cnblogs.com/neru/archive/2011/01/06/1927519.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值