苏木清华

--一些小记录

  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 :: 管理 ::

Windbey中为了增强对集合的访问能力, MS设计了List<T>这么一个泛型集合, 其中有不少的增强功能,比如Foreach,ConvertAll,FindAll等等,并且为了方便使用MS在System名空间下引入了一些特制的Delegate.主要包括以下几个:

   20     public delegate void Action<T>(T obj);   //Used by ForEach

   21     public delegate int Comparison<T>(T x, T y);  //Used by Sort

   22     public delegate TOutput Converter<TInput, TOutput>(TInput input);    //Used by ConvertAll

   23     public delegate bool Predicate<T>(T obj); //Used by FindAll

   20       public delegate T Func<T>();

   21       public delegate T Func<A0, T>(A0 arg0);

   22       public delegate T Func<A0, A1, T>(A0 arg0, A1 arg1);

   23       public delegate T Func<A0, A1, A2, T>(A0 arg0, A1 arg1, A2 arg2);

   24       public delegate T Func<A0, A1, A2, A3, T>(A0 arg0, A1 arg1, A2 arg2, A3 arg3);

 

就是说3.0中特制的Delegate比2.0的更一般化, 2.0是3.0的特例. 所以我们完全可以将lambda表达式运用于List<T>的一些增强方法中.

Sort方法

   20  List<int> list=new List<int>();

   21  var numbers = new []{ 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };

   22  list.AddRange(numbers);

   23  list.Sort(delegate (int a, int b)

   24                {

   25                 return a.CompareTo(b);

   26                }

   27            );

   28  //use lambda

   29  list.Sort((a,b)=>a.CompareTo(b));


ConvertAll方法

   20  List<int> doubleList =list.ConvertAll<int>(delegate (int i)

   21                                             {

   22                                                 return i*2;

   23                                             });

   24  //use lambda

   25  var doubleList2=list.ConvertAll<int>(i=>i*2);


FindAll方法


   20  List<int> lowerThanFiveList =list.FindAll(delegate (int i)

   21                                             {

   22                                                 return i<5;

   23                                             }

   24                                           );

   25  var lowerThanFiveList2=list.FindAll(i=>i<5);


从上面的例子可以看出利用lambda表达式写出的代码更加简洁易懂.  (以后代码都经过编译测试,可不是我杜撰的.)

以上是将lambda表达式运用于2.0当中. 但是在熟悉了3.0后, 你会发现2.0中的List<T>提供的增强方法完全是多余的了. 其实这些增强方法往往并不限于List<T>, 通常对于IEnumerable<T>对象都是适用的. 但是如果去改动IEnumable<T>接口那么影响实在太大了,将涉及很多的类. 所以MS仅仅在List<T>中提供了这些增强方法. 不过通过List<T>的一个构造函数,你可以使得所有的IEnumerable<T>对象可以方便的转化为List<T>,然后再利用这些方法.

这可以说是一个很取巧的方法, 不过在有了3.0的Extension Method的支持下, 就不用这么麻烦了, 而且MS还内置了一系列更强的集合操作方法.

比如之前的FindAll方法,我们现在可以这样写:

   21      var numbers = new []{ 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };

   22      var lowerThanFive=numbers.Where(i=>i<5); //never need List<T>, just operate on T[] or any other types implement IEnumerable<T>

   23      foreach (var v in lowerThanFive)

   24          Console.WriteLine(v);   


ConvertAll方法

   21      var doubleList3=numbers.Select(i=>i*2);

   22      foreach (var v in doubleList3)

   23          Console.WriteLine(v); 


Sort方法

   21      var orderList =numbers.OrderBy(i=>i);

   22      foreach (var v in orderList)

   23          Console.WriteLine(v); 

甚至还有很多更强大的功能:
比如我要取numbers数组中最大的5个数.

   21      var big5 =numbers.OrderByDescending(i=>i).Take(5);

   22      foreach (var v in big5)

   23          Console.WriteLine(v);


 

通过Orcas的Extension Method和Lambda表达式, MS为集合的操作提供了更加方便强大的功能. 这里尚未用到Standard Query Operators, 不然代码还要被简化.

当然Linq现在仅仅是一个Tech Preview 版本. 尚有很多不足.尤其在智能感知(IntelliSense)方面:
1.  var numbers = new []{ 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 }; 采用这种写法时, numbers没有智能感知功能.
2. 使用lambda表达式时,如果不声明T类型,对于其中的变量没有智能感知功能.这点很是奇怪, Linq竟然没有强制声明类型.

   21     var lowerThanFive=numbers.Where<int>(i=>i<5);

   22     var lowerThanFive=numbers.Where(i=>i<5);

以上两种写法竟然都没问题, 显然在下一种写法中变量i 无法获得智能感知的能力. 
3. numbers.OrderBy(...),在写这个方法时,numbers的智能感知中并没有OrderBy这个方法, 但是编译运行没有问题.
4. lambda表达式目前不支持多条语句.

 

===============================

 

//合并数据
            Dictionary<string, Dictionary<string, IEnumerable<Reminder>>> list = new Dictionary<string, Dictionary<string, IEnumerable<Reminder>>>();
            foreach (string type in Types)
            {
                foreach (string way in Ways)
                {
                    IEnumerable<Reminder> list1 = from r in Reminders
                                where r.TYPE == type && r.Way == way
                                select r;
                    if (!list.ContainsKey(type))
                    {
                        Dictionary<string, IEnumerable<Reminder>> wayDic = new Dictionary<string, IEnumerable<Reminder>>();
                        list.Add(type, wayDic);
                    }
                    list[type].Add(way, list1);
                }
            }


//LINQ to DataSet(弱类型 DataSet)
DataSet ds = new DataSet();
ds.Tables.Add();
ds.Tables[0].Columns.Add("Id", System.Type.GetType("System.Int32"));
ds.Tables[0].Columns.Add("Text");

for (int i = 0; i < 10; i++)
{
    DataRow dr = ds.Tables[0].Rows.Add();
    dr["Id"] = i;
    dr["Text"] = "vvv";
}

var tbl = from t in ds.Tables[0].AsEnumerable()
        where t.Field<int>("id") > 3
        select new { Id = t.Field<int>("Id"), Text = t.Field<string>("Text") };


//LINQ to DataSet(强类型 DataSet)
/*
首先,在 App_Code 中新建一个“数据集”项,我们命名为 DataSet1.xsd,并打开它。

其次,在数据库资源管理器中连接数据库,并展开“表”,然后将某个/些表(我们这里是 TranTable)拖到 DataSet1.xsd 的界面中,也可以只拖需要的字段,保存 DataSet1.xsd

 */
DataSet1 ds = new DataSet1();
DataSet1TableAdapters.TranTableTableAdapter adapter = new DataSet1TableAdapters.TranTableTableAdapter();
adapter.Fill(ds.TranTable);

var tbl = from t in ds.TranTable
          select new { Id = t.Id, Priority = t.Priority };

 

posted on 2010-10-19 09:09  苏木清华  阅读(176)  评论(0)    收藏  举报