Linq 延迟执行

来源:互联网 发布:35互联域名证书 编辑:程序博客网 时间:2024/04/30 04:44

使用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