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); } }