vs版本:16.8
下载地址:https://dotnet.microsoft.com/download/dotnet/5.0
解决方案选择.net 5 升级完成
c#6新语法
using System; using System.Collections.Generic; using System.Text; namespace SharpGrammarInfo.SharpSix { public class Student { public Student(string firstName, string lastName) { FirstName = firstName; LastName = lastName; } public int? Id { get; set; } public string FirstName { get; } public string LastName { get; } //对只读属性只能通过构造函数对其初始化值 //public void SetName(string firstName, string lastName) //{ // FirstName = firstName; // LastName = lastName; //} //自动属性初始化表达式 public ICollection<double> Grades { get; } = new List<double>(); //public override string ToString() => $"{LastName}, {FirstName}"; public override string ToString() => $"{FirstName}-{LastName}"; //c#6 新写法 只读自动属性 public string FullName => $"{FirstName}-{LastName}"; //c#6 新写法 只读自动属性 public string FullName1 { get { return $"{FirstName}-{LastName}"; } } //老写法 public string TestName { get; set; } } }
c#7新语法
using System; using System.Collections.Generic; using System.Text; using System.Threading.Tasks; namespace SharpGrammarInfo.SharpSeven { public class SharpSevenInfo { public static void Show() { #region Out变量 { ////不需要声明 //string input = Console.ReadLine(); //int.TryParse(input, out int result); //Console.WriteLine(result); ////out 修改是可以是var类型声明 //int.TryParse(input, out var result1); //Console.WriteLine(result1); //Console.WriteLine("****************Out*****************"); ////out 变量 //DInfo dInfo = new DInfo(123); } #endregion #region 元组 { (string Alpha, string Beta) namedLetters = ("a", "b"); namedLetters.Alpha = "aa"; namedLetters.Beta = "bb"; Console.WriteLine($"{namedLetters.Alpha}, {namedLetters.Beta}"); var alphabetStart = (Alpha: "a", Beta: "b"); alphabetStart.Beta = "B+B"; alphabetStart.Alpha = "A+A"; Console.WriteLine($"{alphabetStart.Alpha}, {alphabetStart.Beta}"); (int max, int min) = Range(); Console.WriteLine(max); Console.WriteLine(min); } { var p = new Point(12, 13); Console.WriteLine(p.X); Console.WriteLine(p.Y); p.Deconstruct(out double xx, out double yy); Console.WriteLine(xx); Console.WriteLine(yy); } #endregion #region 弃元 { var (_, _, _, pop1, _, pop2) = QueryCityDataForYears("New York City", 1960, 2010); (string, double, int, int, int, int) result = QueryCityDataForYears("New York City", 1960, 2010); } #endregion #region 模式 { int input = 123; int sum = 234; if (input is int count) sum += count; } { //IEnumerable<object> enumerablelist = new List<object>() //{ // 0, // new List<int>(){ 0,1,2,3,4,5,6 }, // 100, // null //}; //int iResult = SumPositiveNumbers(enumerablelist); } #region 本地方法 LocalFunction("朝夕教育"); #endregion //#region expression-bodied 成员 //ExpressionMembersExample expression = new ExpressionMembersExample("朝夕教育"); //#endregion //#region throw 表达式 //string[] args = new string[] { "zhaoxi01", "zhaoxi02", "zhaoxi03" }; //string arg = args.Length >= 4 ? args[0] : // throw new ArgumentException("You must supply an argument"); //#endregion #region 默认文本表达式 Func<string, bool> whereClause = default(Func<string, bool>); Func<string, bool> whereClause1 = default; #endregion #region 数字文本语法改进 //二进制数形式写入 //误读的数值常量可能使第一次阅读代码时更难理解。 位掩码或其他符号值容易产生误解。 C# 7.0 包括两项新功能,可用于以最可读的方式写入数字来用于预期用途:二进制文本和数字分隔符 。 //在创建位掩码时,或每当数字的二进制表示形式使代码最具可读性时,以二进制形式写入该数字 int Sixteen = 0b0001_0000; Console.WriteLine(Sixteen); int ThirtyTwo = 0b0010_0000; Console.WriteLine(ThirtyTwo); int SixtyFour = 0b0100_0000; Console.WriteLine(SixtyFour); int OneHundredTwentyEight = 0b1000_0000; Console.WriteLine(OneHundredTwentyEight); //long类型 //常量开头的 0b 表示该数字以二进制数形式写入。 二进制数可能会很长,因此通过引入 _ 作为数字分隔符通常更易于查看位模式,如前面示例中的二进制常量所示。 数字分隔符可以出现在常量的任何位置。 对于十进制数字,通常将其用作千位分隔符。 十六进制和二进制文本可采用 _ 开头: long BillionsAndBillions = 100_000_000_000; Console.WriteLine(BillionsAndBillions); //decimal、float 和 double //数字分隔符也可以与 decimal、float 和 double 类型一起使用: double AvogadroConstant = 6.022_140_857_747_474e23; Console.WriteLine(AvogadroConstant); decimal GoldenRatio = 1.618_033_988_749_894_848_204_586_834_365_638_117_720_309_179M; Console.WriteLine(GoldenRatio); #endregion #region 命名实参 // 该方法可以通过使用位置参数以正常方式调用。 PrintOrderDetails("Gift Shop", 31, "Red Mug"); // 可以按任何顺序为参数提供命名参数。 PrintOrderDetails(orderNum: 31, productName: "Red Mug", sellerName: "Gift Shop"); PrintOrderDetails(productName: "Red Mug", sellerName: "Gift Shop", orderNum: 31); // 与位置参数混合的命名参数有效 // 只要它们被使用在正确的位置。 PrintOrderDetails("Gift Shop", 31, productName: "Red Mug"); PrintOrderDetails(sellerName: "Gift Shop", 31, productName: "Red Mug"); // C# 7.2 onwards PrintOrderDetails("Gift Shop", orderNum: 31, "Red Mug"); // C# 7.2 onwards ////但是,如果使用顺序错误,则混合参数无效。 //// 以下语句将导致编译器错误。 //PrintOrderDetails("Gift Shop", 31, productName: "Red Mug"); //PrintOrderDetails(31, sellerName: "Gift Shop", "Red Mug"); //PrintOrderDetails(31, "Red Mug", sellerName: "Gift Shop"); #endregion #region private protected 访问修饰符---新复合访问修饰符 // 访问修饰符是关键字,用于指定成员或类型已声明的可访问性。 本部分介绍四个访问修饰符: //可使用访问修饰符指定以下六个可访问性级别: //public:访问不受限制。 //protected:访问限于包含类或派生自包含类的类型。 //internal:访问限于当前程序集。 //protected internal:访问限于当前程序集或派生自包含类的类型。 //private:访问限于包含类。 //C#7特有 //private protected:访问限于包含类或当前程序集中派生自包含类的类型。 #endregion #region 增强的泛型约束 ///之前讲的泛型约束有几种? //枚举做基类约束 GerenicInfo<EnumInfo> info = new GerenicInfo<EnumInfo>(); info.Show(EnumInfo.ONE); //约束不能为空 GerenicInfoUnmanaged<int> gerenicInfoUnmanaged = new GerenicInfoUnmanaged<int>(); //GerenicInfoUnmanaged<string> gerenicInfoUnmanaged = new GerenicInfoUnmanaged<string>(); #endregion #region 通用的异步返回类型 //ValueTask<int> task = Func(); //await foreach (var item in task) //{ //} #endregion } public static async ValueTask<int> Func() { await Task.Delay(100); return 5; } /// <summary> /// /// </summary> /// <typeparam name="T"></typeparam> public class GerenicInfo<T> where T : Enum { public void Show(T t) { } } public enum EnumInfo { ONE, TOWN, THREE } public class GerenicInfoUnmanaged<T> where T : unmanaged { public void Show(T t) { } } public static ref int FindRef(int[,] matrix, Func<int, bool> predicate) { for (int i = 0; i < matrix.GetLength(0); i++) { for (int j = 0; j < matrix.GetLength(1); j++) { if (predicate(matrix[i, j])) { return ref matrix[i, j]; } } } throw new InvalidOperationException("Not found"); } public static void PrintOrderDetails(string sellerName, int orderNum, string productName) { if (string.IsNullOrWhiteSpace(sellerName)) { throw new ArgumentException(message: "Seller name cannot be null or empty.", paramName: nameof(sellerName)); } Console.WriteLine($"Seller: {sellerName}, Order #: {orderNum}, Product: {productName}"); } public static string LocalFunction(string name) { return ZhxiToString(name); string ZhxiToString(string name) { return name; } } /// <summary> /// Ref 局部变量和返回结果 /// </summary> /// <param name="matrix"></param> /// <param name="predicate"></param> /// <returns></returns> public static ref int Find(int[,] matrix, Func<int, bool> predicate) { for (int i = 0; i < matrix.GetLength(0); i++) for (int j = 0; j < matrix.GetLength(1); j++) if (predicate(matrix[i, j])) return ref matrix[i, j]; throw new InvalidOperationException("Not found"); } /// <summary> /// 模式 /// </summary> /// <param name="sequence"></param> /// <returns></returns> public static int SumPositiveNumbers(IEnumerable<object> sequence) { int sum = 0; foreach (var i in sequence) { switch (i) { case 0: break; case IEnumerable<int> childSequence: { foreach (var item in childSequence) sum += (item > 0) ? item : 0; break; } case int n when n > 0: sum += n; break; case null: throw new NullReferenceException("Null found in sequence"); default: throw new InvalidOperationException("Unrecognized type"); } } return sum; } private static (string, double, int, int, int, int) QueryCityDataForYears(string name, int year1, int year2) { int population1 = 0, population2 = 0; double area = 0; if (name == "New York City") { area = 468.48; if (year1 == 1960) { population1 = 7781984; } if (year2 == 2010) { population2 = 8175133; } return (name, area, year1, population1, year2, population2); } return ("", 0, 0, 0, 0, 0); } private static (int max, int min) Range() { return (123, 234); } } public class Point { public Point(double x, double y) => (X, Y) = (x, y); public double X { get; } public double Y { get; } public void Deconstruct(out double x, out double y) => (x, y) = (X, Y); } public class BInfo { public BInfo(int i, out string j) { j = i.ToString(); } } public class DInfo : BInfo { public DInfo(int i) : base(i, out var j) { Console.WriteLine($"The value of 'j' is {j}"); } } #endregion }
c#8新语法
using System; using System.Collections.Generic; using System.Text; using System.Threading; using System.Threading.Tasks; namespace SharpGrammarInfo.SharpEight { /// <summary> /// C#8 /// </summary> public class SharpEightInfo { public static void Show() { #region 默认接口方法 CustomInterface interface1 = new CustomClass(); interface1.Show(); interface1.ShowInfo(); #endregion #region switch 表达式 //老玩法 string week3 = WeekToStringSwitch(WeekInfo.Monday); string week4 = WeekToStringSwitch(WeekInfo.Tuesday); string week5 = WeekToStringSwitch(WeekInfo.Wednesday); //新玩法 string week = WeekToString(WeekInfo.Wednesday); string week1 = WeekToString(WeekInfo.Tuesday); string week2 = WeekToString(WeekInfo.Wednesday); #endregion #region 属性模式 PropertyPattern product = new PropertyPattern() { ProductName = "朝夕架构班", Price = 5499 }; PropertyPattern product1 = new PropertyPattern() { ProductName = "朝夕高级班", Price = 4299 }; double price = PropertyPatternShow(product); #endregion #region 元组模式 string strResult = RockPaperScissors("朝夕", "教育1"); string strResult1 = RockPaperScissors("朝夕", "教育"); string strResult3 = RockPaperScissors("朝夕", "教育3"); #endregion #region 位置模式 PointInfo point = new PointInfo(123, 234); int i = 11; int j = 12; point.Deconstruct(out i, out j); #endregion #region 静态本地函数 M(); static int M() { int y = 5; int x = 7; return Add(x, y); static int Add(int left, int right) => left + right; } #endregion #region 可空引用类型 //string? str = null; //string str1 = null; #endregion #region 异步流 AsyncIEnumerableShow(); #endregion } /// <summary> /// C#8新语法 /// 如果enum是summation类型的话其实|也可以不需要|| /// </summary> /// <param name="week"></param> /// <returns></returns> public static string WeekToString(WeekInfo week) => week switch { WeekInfo.Monday | WeekInfo.Tuesday => "周一",//正常使用 WeekInfo.Wednesday or WeekInfo.Thursday => "周三",//编译不报错 运行时报错 WeekInfo.Friday => "周五", WeekInfo.Saturday => "周六", WeekInfo.Sunday => "周七", _ => throw new NotImplementedException("枚举不存在"), }; /// <summary> ///switch 经典switch /// </summary> /// <param name="week"></param> /// <returns></returns> public static string WeekToStringSwitch(WeekInfo week) { switch (week) { case WeekInfo.Monday: return "周一"; case WeekInfo.Tuesday: return "周二"; case WeekInfo.Wednesday: return "周三"; case WeekInfo.Thursday: return "周四"; case WeekInfo.Friday: return "周五"; case WeekInfo.Saturday: return "周六"; case WeekInfo.Sunday: return "周七"; default: throw new NotImplementedException("枚举不存在"); } } /// <summary> ///switch 属性模式 /// </summary> /// <param name="pattern"></param> /// <returns></returns> public static double PropertyPatternShow(PropertyPattern pattern) => pattern switch { { ProductName: "朝夕架构班" } => pattern.Price * 0.5, _ => throw new NotImplementedException(), }; /// <summary> /// switch 元组模式 /// </summary> /// <param name="first"></param> /// <param name="second"></param> /// <returns></returns> public static string RockPaperScissors(string first, string second) => (first, second) switch { ("朝夕", "教育1") => $"{first}-{second}", ("朝夕", "教育2") => $"{first}-{second}", ("朝夕", "教育3") => $"{first}-{second}", (_, _) => "不匹配" }; /// <summary> /// using 声明 /// </summary> /// <param name="lines"></param> /// <returns></returns> public static int WriteLinesToFile(IEnumerable<string> lines) { { using (var file1 = new System.IO.StreamWriter("WriteLines2.txt")) { int skippedLines1 = 0; foreach (string line in lines) { if (!line.Contains("Second")) { file1.WriteLine(line); } else { skippedLines1++; } } // Notice how skippedLines is in scope here. return skippedLines1; // file is disposed here } } { using var file = new System.IO.StreamWriter("WriteLines2.txt"); int skippedLines = 0; foreach (string line in lines) { if (!line.Contains("Second")) { file.WriteLine(line); } else { skippedLines++; } } // Notice how skippedLines is in scope here. return skippedLines; // file is disposed here } } /// <summary> /// 异步流 /// </summary> public async static void AsyncIEnumerableShow() { Console.WriteLine("********************异步流*********************"); IAsyncEnumerable<int> asynclist = GenerateSequence(); await foreach (var item in asynclist) { Console.WriteLine(item); } Console.WriteLine("********************异步流*********************"); } public static async IAsyncEnumerable<int> GenerateSequence() { for (int i = 0; i < 20; i++) { await Task.Delay(1000).ContinueWith(s => { Console.WriteLine($"线程ID:{Thread.CurrentThread.ManagedThreadId.ToString("000")}"); }); yield return i; } } } public enum WeekInfo { Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday } }
c#9新语法
using System; using System.Collections.Generic; using System.Linq.Expressions; using System.Text; namespace SharpGrammarInfo.SharpNine { /// <summary> /// C#9 /// </summary> public class SharpNineInfo { public static void Show() { //记录 { FooInfo fooInfo = new FooInfo() { PropA = "张三", PropB = "李四" }; fooInfo.PropA = "张三++"; fooInfo.PropB = "张三++"; var PropA = fooInfo.PropA; var PropB = fooInfo.PropB; ///为了满足,在一段程序执行过程中,有部分数据只是作为一个记录, ///一旦赋值不能修改; //FooInfo001 fooInfo001 = new FooInfo001() //{ // PropA = "123456", // PropB = "456789" //}; //fooInfo001.PropA = "5678"; //fooInfo001.PropB = "测试"; FooInfo002 fooInfo002 = new FooInfo002("5678", "测试"); string propa = fooInfo002.PropA; string propb = fooInfo002.PropB; //fooInfo002.PropA = ""; //Init是针对于类内部的字段而言; FooInfo003 fooInfo003 = new FooInfo003() { PropA = "FooInfo003", PropB = "FooInfo003_1" }; //fooInfo003.PropA = "";//报错 //fooInfo003.PropB = "";//报错 string propa3 = fooInfo003.PropA; string propb3 = fooInfo003.PropB; //Record关键字 Person person = new Person("朝夕", "教育"); string firstName = person.FirstName; string lastName = person.LastName; //person.LastName = "培训";//报错 var otherPerson = person with { FirstName = "武汉朝夕" }; Console.WriteLine(object.ReferenceEquals(person, otherPerson)); Teacher teacher = new Teacher("朝夕", "教育", "科技有限公司"); string firstname1 = teacher.FirstName; //teacher.FirstName = "";//报错了 var teachernew = teacher with { }; //with 表达式指示编译器创建记录的副本 Console.WriteLine(object.ReferenceEquals(teacher, teachernew)); }; #region 顶级语句 //见控制台输出语句 #endregion //简化 #region 对象声明 { //FooInfo foo = new FooInfo(); FooInfo fooInfo1 = new(); //语法糖 FooInfo fooInfo2 = new() { PropA = "123", PropB = "234" }; } #endregion #region 方法调用 { var result = ForecastFor(1, "Richard", new()); } #endregion #region 静态修饰 { Func<int> func = static () => 1; } #endregion #region 模式匹配 char a = 'A'; bool bResult = a.IsLetterNew(); #endregion #region 为空判断 string name = "Ricahrd"; if (string.IsNullOrWhiteSpace(name)) { } if (name is not null) { } #endregion #region 协变式返回值(Covariant returns) { } #endregion #region nint { // 原生大小的数字类型 //这次引入一组新类型(nint,nuint,nfloat等)'n'表示native(原生),该特性允许声明一个32位或64位的数据类型,这取决于操作系统的平台类型。 nint nativeInt = 55; //在32位主机中编译时,需要4个字节。 nint nativeInt1 = 55; //使用x64编译设置在64位主机中编译时需要8个字节。 //uint; } #endregion #region Lambda 参数弃元 { // C# 9 之前 Func<int, int, int> zero = (a, b) => 0; Func<int, int, int> func = delegate (int a, int b) { return 0; }; } // C# 9 { Func<int, int, int> zero = (_, _) => 0; Func<int, int, int> func = delegate (int _, int _) { return 0; }; } //在 C# 9 之前,即便不使用的 Lambda 参数也需要给它命名。C# 9 支持弃元参数一方面简化了命名, //另一方面也节省了内存分配。更重要的是它使得编程的意图更明确,让人一看就知道这个参数是不用的, //增强了代码的可读性和可维护性。 #endregion } private static SharpNineInfo ForecastFor(int id, string name, FooInfo fooInfo) { return new(); } private static Expression<Func<UserInfo, bool>> expression = u => u.Id > 0; } public static class SharpNineInfoExtension { public static bool IsLetterNew(this char c) => c is (>= 'a' and <= 'z') or >= 'A' and <= 'Z'; } }