Ejemplo n.º 1
0
        public static void OtherInterestingFeatures()
        {
            // OPTIONAL PARAMETERS
            MethodSignatures(3, 1, 3, "Some", "Extra", "Strings");
            MethodSignatures(3, another: 3); // explicity set a parameter, skipping optional ones

            // EXTENSION METHODS
            int i = 3;
            i.Print(); // Defined below

            // NULLABLE TYPES - great for database interaction / return values
            // any value type (i.e. not a class) can be made nullable by suffixing a ?
            // <type>? <var name> = <value>
            int? nullable = null; // short hand for Nullable<int>
            Console.WriteLine("Nullable variable: " + nullable);
            bool hasValue = nullable.HasValue; // true if not null

            // ?? is syntactic sugar for specifying default value (coalesce)
            // in case variable is null
            int notNullable = nullable ?? 0; // 0

            // IMPLICITLY TYPED VARIABLES - you can let the compiler work out what the type is:
            var magic = "magic is a string, at compile time, so you still get type safety";
            // magic = 9; will not work as magic is a string, not an int

            // TEMPLATES
            var phonebook = new Dictionary<string, string>() { 
                {"Sarah", "212 555 5555"} // Add some entries to the phone book
            };

            // Calling SETDEFAULT defined as a template above
            Console.WriteLine(SetDefault<string,string>(phonebook, "Shaun", "No Phone")); // No Phone
            // nb, you don't need to specify the TKey and TValue since they can be 
            // derived implicitly
            Console.WriteLine(SetDefault(phonebook, "Sarah", "No Phone")); // 212 555 5555

            // LAMBDA EXPRESSIONS - allow you to write code in line
            Func<int, int> square = (x) => x * x; // Last T item is the return value
            Console.WriteLine(square(3)); // 9

            // PARALLEL FRAMEWORK
            // http://blogs.msdn.com/b/csharpfaq/archive/2010/06/01/parallel-programming-in-net-framework-4-getting-started.aspx
            var websites = new string[] { 
                "http://www.google.com", "http://www.reddit.com", 
                "http://www.shaunmccarthy.com"
            };
            var responses = new Dictionary<string, string>();
            
            // Will spin up separate threads for each request, and join on them
            // before going to the next step!
            Parallel.ForEach(websites, 
                new ParallelOptions() {MaxDegreeOfParallelism = 3}, // max of 3 threads
                website =>
            {
                // Do something that takes a long time on the file
                using (var r = WebRequest.Create(new Uri(website)).GetResponse())
                {
                    responses[website] = r.ContentType;
                }
            });

            // This won't happen till after all requests have been completed
            foreach (var key in responses.Keys)
                Console.WriteLine("{0}:{1}", key, responses[key]);

            // DYNAMIC OBJECTS (great for working with other languages)
            dynamic student = new ExpandoObject();
            student.FirstName = "First Name"; // No need to define class first!

            // You can even add methods (returns a string, and takes in a string)
            student.Introduce = new Func<string, string>(
                (introduceTo) => string.Format("Hey {0}, this is {1}", student.FirstName, introduceTo));
            Console.WriteLine(student.Introduce("Beth"));

            // IQUERYABLE<T> - almost all collections implement this, which gives you a lot of 
            // very useful Map / Filter / Reduce style methods
            var bikes = new List<Bicycle>();
            bikes.Sort(); // Sorts the array
            bikes.Sort((b1, b2) => b1.Wheels.CompareTo(b2.Wheels)); // Sorts based on wheels
            var result = bikes
                .Where(b => b.Wheels > 3) // Filters - chainable (returns IQueryable of previous type)
                .Where(b => b.IsBroken && b.HasTassles)
                .Select(b => b.ToString()); // Map - we only this selects, so result is a IQueryable<string>

            var sum = bikes.Sum(b => b.Wheels); // Reduce - sums all the wheels in the collection

            // Create a list of IMPLICIT objects based on some parameters of the bike
            var bikeSummaries = bikes.Select(b=>new { Name = b.Name, IsAwesome = !b.IsBroken && b.HasTassles });
            // Hard to show here, but you get type ahead completion since the compiler can implicitly work
            // out the types above!
            foreach (var bikeSummary in bikeSummaries.Where(b => b.IsAwesome))
                Console.WriteLine(bikeSummary.Name);

            // ASPARALLEL
            // And this is where things get wicked - combines linq and parallel operations
            var threeWheelers = bikes.AsParallel().Where(b => b.Wheels == 3).Select(b => b.Name);
            // this will happen in parallel! Threads will automagically be spun up and the 
            // results divvied amongst them! Amazing for large datasets when you have lots of 
            // cores

            // LINQ - maps a store to IQueryable<T> objects, with delayed execution
            // e.g. LinqToSql - maps to a database, LinqToXml maps to an xml document
            var db = new BikeRespository();

            // execution is delayed, which is great when querying a database
            var fitler = db.Bikes.Where(b => b.HasTassles); // no query run
            if (42 > 6) // You can keep adding filters, even conditionally - great for "advanced search" functionality
                fitler = fitler.Where(b => b.IsBroken); // no query run

            var query = fitler
                .OrderBy(b => b.Wheels)
                .ThenBy(b => b.Name)
                .Select(b => b.Name); // still no query run

            // Now the query runs, but opens a reader, so only populates are you iterate through
            foreach (string bike in query) 
                Console.WriteLine(result);

        }
        public static void OtherInterestingFeatures()
        {
            // 可选参数
            MethodSignatures(3, 1, 3, "Some", "Extra", "Strings");
            MethodSignatures(3, another: 3); // 显式指定参数,忽略可选参数

            // 扩展方法
            int i = 3;

            i.Print(); // 参见下面的定义

            // 可为null的类型 对数据库交互、返回值很有用
            // 任何值类型 (i.e. 不为类) 添加后缀 ? 后会变为可为null的值
            // <类型>? <变量名> = <值>
            int?nullable = null;  // Nullable<int> 的简写形式

            Console.WriteLine("Nullable variable: " + nullable);
            bool hasValue = nullable.HasValue; // 不为null时返回真
            // ?? 是用于指定默认值的语法糖
            // 以防变量为null的情况
            int notNullable = nullable ?? 0; // 0

            // 变量类型推断 - 你可以让编译器推断变量类型:
            var magic = "编译器确定magic是一个字符串,所以仍然是类型安全的";
            // magic = 9; // 不工作,因为magic是字符串,而不是整数。

            // 泛型
            //
            var phonebook = new Dictionary <string, string>()
            {
                { "Sarah", "212 555 5555" } // 在电话簿中加入新条目
            };

            // 调用上面定义为泛型的SETDEFAULT
            Console.WriteLine(SetDefault <string, string>(phonebook, "Shaun", "No Phone")); // 没有电话
            // 你不用指定TKey、TValue,因为它们会被隐式地推导出来
            Console.WriteLine(SetDefault(phonebook, "Sarah", "No Phone"));                  // 212 555 5555

            // lambda表达式 - 允许你用一行代码搞定函数
            Func <int, int> square = (x) => x * x; // 最后一项为返回值

            Console.WriteLine(square(3));          // 9

            // 可抛弃的资源管理 - 让你很容易地处理未管理的资源
            // 大多数访问未管理资源 (文件操作符、设备上下文, etc.)的对象
            // 都实现了IDisposable接口。
            // using语句会为你清理IDisposable对象。
            using (StreamWriter writer = new StreamWriter("log.txt"))
            {
                writer.WriteLine("这里没有什么可疑的东西");
                // 在作用域的结尾,资源会被回收
                // (即使有异常抛出,也一样会回收)
            }

            // 并行框架
            // http://blogs.msdn.com/b/csharpfaq/archive/2010/06/01/parallel-programming-in-net-framework-4-getting-started.aspx
            var websites = new string[] {
                "http://www.google.com", "http://www.reddit.com",
                "http://www.shaunmccarthy.com"
            };
            var responses = new Dictionary <string, string>();

            // 为每个请求新开一个线程
            // 在运行下一步前合并结果
            Parallel.ForEach(websites,
                             new ParallelOptions()
            {
                MaxDegreeOfParallelism = 3
            },                                                      // max of 3 threads
                             website =>
            {
                // Do something that takes a long time on the file
                using (var r = WebRequest.Create(new Uri(website)).GetResponse())
                {
                    responses[website] = r.ContentType;
                }
            });

            // 直到所有的请求完成后才会运行下面的代码
            foreach (var key in responses.Keys)
            {
                Console.WriteLine("{0}:{1}", key, responses[key]);
            }

            // 动态对象(配合其他语言使用很方便)
            dynamic student = new ExpandoObject();

            student.FirstName = "First Name"; // 不需要先定义类!

            // 你甚至可以添加方法(接受一个字符串,输出一个字符串)
            student.Introduce = new Func <string, string>(
                (introduceTo) => string.Format("Hey {0}, this is {1}", student.FirstName, introduceTo));
            Console.WriteLine(student.Introduce("Beth"));

            // IQUERYABLE<T> - 几乎所有的集合都实现了它,
            // 带给你 Map / Filter / Reduce 风格的方法
            var bikes = new List <Bicycle>();

            bikes.Sort();                                           // Sorts the array
            bikes.Sort((b1, b2) => b1.Wheels.CompareTo(b2.Wheels)); // 根据车轮数排序
            var result = bikes
                         .Where(b => b.Wheels > 3)                  // 筛选 - 可以连锁使用 (返回IQueryable)
                         .Where(b => b.IsBroken && b.HasTassles)
                         .Select(b => b.ToString());                // Map - 这里我们使用了select,所以结果是IQueryable<string>

            var sum = bikes.Sum(b => b.Wheels);                     // Reduce - 计算集合中的轮子总数

            // 创建一个包含基于自行车的一些参数生成的隐式对象的列表
            var bikeSummaries = bikes.Select(b => new { Name = b.Name, IsAwesome = !b.IsBroken && b.HasTassles });

            // 很难演示,但是编译器在代码编译完成前就能推导出以上对象的类型
            foreach (var bikeSummary in bikeSummaries.Where(b => b.IsAwesome))
            {
                Console.WriteLine(bikeSummary.Name);
            }

            // ASPARALLEL
            // 邪恶的特性 —— 组合了linq和并行操作
            var threeWheelers = bikes.AsParallel().Where(b => b.Wheels == 3).Select(b => b.Name);
            // 以上代码会并发地运行。会自动新开线程,分别计算结果。
            // 适用于多核、大数据量的场景。

            // LINQ - 将IQueryable<T>映射到存储,延缓执行
            // 例如 LinqToSql 映射数据库, LinqToXml 映射XML文档
            var db = new BikeRespository();

            // 执行被延迟了,这对于查询数据库来说很好
            var filter = db.Bikes.Where(b => b.HasTassles); // 不运行查询

            if (42 > 6)                                     // 你可以不断地增加筛选,包括有条件的筛选,例如用于“高级搜索”功能
            {
                filter = filter.Where(b => b.IsBroken);     // 不运行查询
            }
            var query = filter
                        .OrderBy(b => b.Wheels)
                        .ThenBy(b => b.Name)
                        .Select(b => b.Name); // 仍然不运行查询

            // 现在运行查询,运行查询的时候会打开一个读取器,所以你迭代的是一个副本
            foreach (string bike in query)
            {
                Console.WriteLine(result);
            }
        }