zoukankan      html  css  js  c++  java
  • Linq学习之旅——Linq to Objects之延期执行方法(下篇)

    目录

    1,Intersect 方法

    2,Except 方法

    3,Range 方法

    4,Repeat 方法

    5,Empty 方法

    6,DefaultIfEmpty 方法

    7,Cast 方法

    8,OfType 方法

    9,AsEnumerable方法

        本篇继续学习剩余的延期执行方法。

    1,Intersect 方法

      Intersect 方法用于生成两个序列的交集。

                string[] names = { "郭靖", "李莫愁", "欧阳晓晓", "黄蓉", "黄药师" };
                string[] names2 = { "郭靖", "杨过", "欧阳晓晓" };
    
                Console.WriteLine("相交的元素");
                foreach (var name in names.Intersect(names2))
                {
                    Console.Write(name + " ");
                }

    输出结果:

    相交的元素
    郭靖 欧阳晓晓

    自定义IEqualityComparer<T>

            public class MyEqualityComparer<T> : IEqualityComparer<T>
            {
                #region IEqualityComparer<T> 成员
    
                public bool Equals(T x, T y)
                {
                    string temp = x as string;
                    if (temp != null)
                    {
                        if (temp == "欧阳晓晓") //对"欧阳晓晓"不过滤
                            return false;
                    }
                    if (x.GetHashCode() == y.GetHashCode())
                        return true;
                    else
                        return false;
                }
    
                public int GetHashCode(T obj)
                {
                    return obj.GetHashCode();
                }
    
                #endregion
            }
               string[] names = { "郭靖", "李莫愁", "欧阳晓晓", "黄蓉", "黄药师" };
                string[] names2 = { "郭靖", "杨过", "欧阳晓晓" };
    
                Console.WriteLine("相交的元素");
                foreach (var name in names.Intersect(names2,new MyEqualityComparer<string>()))
                {
                    Console.Write(name + " ");
                }

    输出结果:

    相交的元素
    郭靖

    2,Except 方法

        Except 方法用于生成两个序列的差集。

    注意:返回是第一个数组里,去掉指定数组里的元素后,剩下的一个序列。

    它和Intersect方法不是互补的,不要搞混了。下面的“杨过”就不会输出。因为它是指定数组里的元素,和源数组一毛钱关系都没有。

                string[] names = { "郭靖", "李莫愁", "欧阳晓晓", "黄蓉", "黄药师" };
                string[] names2 = { "郭靖", "杨过", "欧阳晓晓" };
    
                Console.WriteLine("2个数组的不同元素");
                foreach (var name in names.Except(names2))
                {
                    Console.Write(name + " ");
                }

    输出结果:

    2个数组的不同元素
    李莫愁 黄蓉 黄药师

    运用自定义IEqualityComparer<T>指定比较器。

                string[] names = { "郭靖", "李莫愁", "欧阳晓晓", "黄蓉", "黄药师" };
                string[] names2 = { "郭靖", "杨过", "欧阳晓晓" };
    
                Console.WriteLine("2个数组的不同元素");
                foreach (var name in names2.Except(names,new MyEqualityComparer<string>()))
                {
                    Console.Write(name + " ");
                }

    输出结果:

    2个数组的不同元素
    杨过 欧阳晓晓

    3,Range 方法

        Range 方法用于生成指定范围的整数序列。在BS程序中,经常需要分页显示,在页面中需要显示页面号码的链接,用这个方法可以生成页码的数组。

    由于没有this关键字,它是一个普通的静态方法。

                int istart = 1;//起始页码
                int iend = 12; //结束页码
    
                var pages = Enumerable.Range(1, iend - istart + 1);
                Console.WriteLine("输出页码");
                foreach (var n in pages)
                {
                    Console.Write("[{0}] ", n);
                }

    输出结果:

    输出页码
    [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12]

    4,Repeat 方法

        Repeat 方法用于生成指定数量重复元素的序列。由于没有this关键字,它是一个普通的静态方法。

                var people = new { Name = "郭靖", Age = 35 };//定义一个匿名类型
    
                var peoples = Enumerable.Repeat(people, 4);
    
                Console.WriteLine("包含4个匿名元素:");
                foreach (var n in peoples)
                {
                    Console.WriteLine("{0} {1} ", n.Name, n.Age);
                }

    输出结果:

    包含4个匿名元素:
    郭靖 35 
    郭靖 35 
    郭靖 35 
    郭靖 35 

    5,Empty 方法

        Empty 方法用于获取一个指定类型参数的空序列。由于没有this关键字,它是一个普通的静态方法。

               var s = Enumerable.Empty<string>();
    
                Console.WriteLine("序列的元素数:{0} ", s.Count());

    输出结果:

    序列的元素数:0 

    6,DefaultIfEmpty 方法

        DefaultIfEmpty 方法用于获取序列,如果序列为空则添加一个类型的默认值。例如:如果元素为引用类型,添加null元素;元素为int类型,则添加int的默认值0。

                string[] names = { "郭靖", "李莫愁", "欧阳晓晓", "黄蓉", "黄药师" };
                var intempty = Enumerable.Empty<int>();//空的Int类型序列
                //没有找到元素的序列
                var empty = from n in names
                            where n.Length == 5
                            select n;
                Console.WriteLine("DefaultIfEmpty 返回有内容的序列");
                foreach (var n in names)
                {
                    Console.Write("{0} ", n);
                }
                Console.WriteLine("\nempty空序列元素数:{0}", empty.Count());
                Console.WriteLine("empty空序列应用DefaultIfEmpty 后的元素数:{0}", empty.DefaultIfEmpty().Count());
                Console.Write("empty空序列应用DefaultIfEmpty 后的元素值:");
                foreach (var n in empty.DefaultIfEmpty())
                {
                    if (n == null)
                        Console.Write("null");
                }
                Console.WriteLine("\n****************************************");
                Console.WriteLine("intempty空序列元素数:{0}", intempty.Count());
                Console.WriteLine("intempty空序列应用DefaultIfEmpty 后的元素数:{0}", intempty.DefaultIfEmpty().Count());
                Console.Write("intempty空序列应用DefaultIfEmpty 后的元素值:");
                foreach (var n in intempty.DefaultIfEmpty())
                {
                    Console.Write(n);
                }

    输出结果:

    DefaultIfEmpty 返回有内容的序列
    郭靖 李莫愁 欧阳晓晓 黄蓉 黄药师 
    empty空序列元素数:0
    empty空序列应用DefaultIfEmpty 后的元素数:1
    empty空序列应用DefaultIfEmpty 后的元素值:null
    ****************************************
    intempty空序列元素数:0
    intempty空序列应用DefaultIfEmpty 后的元素数:1
    intempty空序列应用DefaultIfEmpty 后的元素值:0

    这个方法还可以指定一个自定义的默认值。

                var intempty = Enumerable.Empty<int>();//空的Int类型序列
                Console.Write("int 类型自定义默认值:");
                foreach (var i in intempty.DefaultIfEmpty(200))
                {
                    Console.Write(i);
                }

    输出结果:

    int 类型自定义默认值:200

    7,Cast 方法

        Cast 方法用于按照TResult类型转换IEnumerable序列的集合。

                //ArrayList没有实现IEnumerable<T>接口
                ArrayList names = new ArrayList();
                names.Add("郭靖");
                names.Add("李莫愁");
                names.Add("欧阳晓晓");
    
                IEnumerable<string> newNames = names.Cast<string>();
                foreach (var s in newNames)
                {
                    Console.WriteLine(s);
                }

    输出结果:

    郭靖
    李莫愁
    欧阳晓晓

    8,OfType 方法

        OfType 方法用于根据TResult类型筛选IEnumerable类型序列的元素。它的用途和Cast方法类似,但OfType方法如果遇到不能强制转换成TResutl的类型,会丢弃该元素,而不会出现运行错误。

                //ArrayList没有实现IEnumerable<T>接口
                ArrayList names = new ArrayList();
                names.Add("郭靖");
                names.Add("李莫愁");
                names.Add(100);
                names.Add(new Stack());
                names.Add("欧阳晓晓");
    
                IEnumerable<string> newNames = names.OfType<string>();
                foreach (var s in newNames)
                {
                    Console.WriteLine(s);
                }

    输出结果:

    郭靖
    李莫愁
    欧阳晓晓

    9,AsEnumerable方法

        AsEnumerable方法根据元素的类型转换为泛型IEnumerable<T>类型。

    MSDN上的一个例子,AsEnumerable用于隐藏自己定义的和IEnumerable里的扩展方法同名的方法。

            public class MyList<T> : List<T>
            {
                public IEnumerable<T> Where(Func<T, bool> predicate)
                {
                    Console.WriteLine("In MyList of Where");
                    return Enumerable.Where(this, predicate);
                }
            }
            private void AsEnumerableDemo()
            {
                MyList<string> list = new MyList<string>() { "郭靖", "黄蓉", "黄药师" };
    
                var query1 = list.Where(n => n.Contains(""));
                Console.WriteLine("query1 created");
                
                var query2 = list.AsEnumerable().Where(n => n.Contains(""));
                Console.WriteLine("query2 created");
            }

    运行结果:

    In MyList of Where
    query1 created
    query2 created

    AsEnumerable方法经常用于Linq To SQL查询,将IQueryable<T>转换成IEnumerable<T>接口。因为一些扩展方法,如Reverse等,虽然在IQueryable<T>里有定义,但并不能将其翻译成对应的SQL语句,所以运行时会报错。用AsEnumerable方法转换成IEnumerable<T>后,实际的数据就在内存中操作。关于IQueryable<T>调用AsEnumerable背后的转换本质,有待进一步考证。

  • 相关阅读:
    『Asp.Net 组件』第一个 Asp.Net 服务器组件:自己的文本框控件
    『Asp.Net 组件』Asp.Net 服务器组件 的开发优势和劣势
    『开源』简单的代码统计工具 开源啦[有图有真相]
    文件中的类都不能进行设计,因此未能为该文件显示设计器。设计器检查出文件中有以下类: FormMain --- 未能加载基类
    DB2:FETCH FIRST 1 ROWS ONLY
    IEnumerable的几个简单用法
    一个字符串中包含逗号个数
    字符串处理总结之一(C#String类)
    C# 中DateTime的各种使用
    C# 键值对类相关
  • 原文地址:https://www.cnblogs.com/xiashengwang/p/2613945.html
Copyright © 2011-2022 走看看