Linq 延迟执行

使用Linq时,其中一个重要概念就是延迟执行,所有的谓词求值需要等到触发时才会被调用。在声明时,它们是不执行的,除非调用Lambda表达式,造成其中的代码开始执行,否则不会被执行。如果Lambda表达式执行的代价比较高(如调用数据库,密集计算等),那么为了优化代码,通过使用”ToXXX”方法来转换为集合方式,减少Lambda表达式的执行。但转换后会造成整个结果都加载到内存(在此之前可能驻留在一个数据库或文件中)。除此之外,”ToXXX”方法会创建基础数据的”快照”,需保证在查询”ToXXX”方法的结果时,不会返回新的结果。测试代码如下:

public class Patent {
        // Title of the published application
        public string Title { get; set; }

        // the date the application was officially published
        public string YearOfPublication { get; set; }
        // A unique number assigned to published application
        public string ApplicationNumber { get; set; }

        public long[] InventorIds { get; set; }

        public override string ToString()
        {
            return string.Format("{0}({1})",Title,YearOfPublication);
        }
    };

    public class Inventor
    {
        public long Id { get; set; }
        public string Name { get; set; }
        public string City { get; set; }
        public string State { get; set; }
        public string Country { get; set; }

        public override string ToString()
        {
            return string.Format("{0}({1},{2})",Name,City,State);
        }
    };

    public static class PatentData
    {
        public static readonly Inventor[] Inventors = new Inventor[]
        {
            new Inventor(){
                Name = "Benjamin Franklin", City = "Philadelphis",
                State = "PA",Country = "USA", Id = 1
            },

            new Inventor() {
                Name = "Orville Wright", City = "Kitty Hawk",
                State = "NC", Country = "USA", Id = 2
            },
            new Inventor() {
                Name = "Wilbur Wright", City = "New York",
                State = "NC", Country = "USA", Id = 3
            },

            new Inventor() {
                Name = "Samuel Morse", City = "Kitty Hawk",
                State = "NC", Country = "USA", Id = 4
            }
        };

        public static readonly Patent[] Patents = new Patent[] { 
            new Patent() {
                Title = "Bifocals", YearOfPublication = "1784",
                InventorIds = new long[] {1}
            },

            new Patent() {
                Title = "Phonograph", YearOfPublication = "1877",
                InventorIds = new long[] {1}
            },
            new Patent() {
                Title = "Kinetoscope", YearOfPublication = "1888",
                InventorIds = new long[] {1}
            },
            new Patent() {
                Title = "Electrical Telegraph", YearOfPublication = "1837",
                InventorIds = new long[] {4}
            },
            new Patent() {
                Title = "Flying machine", YearOfPublication = "1903",
                InventorIds = new long[] {2,3}
            },
            new Patent() {
                Title = "Steam Locomotive", YearOfPublication = "1815",
                InventorIds = new long[] {5}
            },
            new Patent() {
                Title = "Droplet depositon apparatus", YearOfPublication = "1989",
                InventorIds = new long[] {6}
            },
            new Patent() {
                Title = "Backless Brassiere", YearOfPublication = "1914",
                InventorIds = new long[] {7}
            },
        };
    
    };

    class Program
    {
        private static void Print<T>(IEnumerable<T> items)
        { 
            foreach(T item in items) {
                Console.WriteLine(item);
            }
        }

        static void Main(string[] args)
        {
            IEnumerable<Patent> patents = PatentData.Patents;
            bool result;

            patents = patents.Where(
                patent => {
                    if (result = patent.YearOfPublication.StartsWith("18"))
                    {
                        // Side effects like this in a predicate are used here
                        // to demonstrate a principle and should generally be avoided
                        //Console.WriteLine("====Begin Compute======");
                        Console.WriteLine("\t" + patent);
                        //Console.WriteLine("====End Compute======");
                    }
                    return result;
                }
                );

            Console.WriteLine("1. Patents prior to the 1900s are:");
            foreach (Patent patent in patents)
            {
                Console.WriteLine("Hello in patent.");
            }

            Console.WriteLine();
            Console.WriteLine("2. A second listing of patents prior to the 1900s:");
            Console.WriteLine(" There are {0} patents prior to 1900.",patents.Count());
            Console.WriteLine();
            Console.WriteLine("3. A third listing of patents prior to the 1900s:");
            patents = patents.ToArray();
            Console.Write(" There are ");
            Console.WriteLine(" {0} patents prior to 1900.",patents.Count());

            Console.ReadLine();
        }
    }
执行结果如下:

1. Patents prior to the 1900s are:
        Phonograph(1877)
Hello in patent.
        Kinetoscope(1888)
Hello in patent.
        Electrical Telegraph(1837)
Hello in patent.
        Steam Locomotive(1815)
Hello in patent.

2. A second listing of patents prior to the 1900s:
        Phonograph(1877)
        Kinetoscope(1888)
        Electrical Telegraph(1837)
        Steam Locomotive(1815)
 There are 4 patents prior to 1900.

3. A third listing of patents prior to the 1900s:
        Phonograph(1877)
        Kinetoscope(1888)
        Electrical Telegraph(1837)
        Steam Locomotive(1815)
 There are  4 patents prior to 1900.
具体代码分析详见<<C#本质论>>(第三版)。


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值