• C#3 到C#9,每个版本添加的功能,待更新


    C#2:

      1.泛型

    C#3:

           1.主要是linq

      2.拉姆达表达式

    C#4:

      1.可选参数

      2.异步 async ... await ...

      异步的例子:

    C#5:

    C#6:

      1.  ?.操作符,和??操作符类似

      2. using静态指令。using static <静态方法的类名>,就可以在下文中,只写静态方法,而不用带出类名。

      参考地址:https://docs.microsoft.com/zh-cn/dotnet/csharp/language-reference/keywords/using-static

      3.

    using System;
    
    public class Circle
    {
       public Circle(double radius)
       {
          Radius = radius;
       }
    
       public double Radius { get; set; }
    
       public double Diameter
       {
          get { return 2 * Radius; }
       }
    
       public double Circumference
       {
          get { return 2 * Radius * Math.PI; }
       }
    
       public double Area
       {
          get { return Math.PI * Math.Pow(Radius, 2); }
       }
    }

    使用Math类使用using静态指令后,使用Math类中的静态方法和静态成员就不用了带类名了。

    using System;
    using static System.Math;
    
    public class Circle
    {
       public Circle(double radius)
       {
          Radius = radius;
       }
    
       public double Radius { get; set; }
    
       public double Diameter
       {
          get { return 2 * Radius; }
       }
    
       public double Circumference
       {
          get { return 2 * Radius * PI; }
       }
    
       public double Area
       {
          get { return PI * Pow(Radius, 2); }
       }
    }

    3. case () when 语句

    using System;
    
    public abstract class Shape
    {
       public abstract double Area { get; }
       public abstract double Circumference { get; }
    }
    
    public class Rectangle : Shape
    {
       public Rectangle(double length, double width)
       {
          Length = length;
          Width = width;
       }
    
       public double Length { get; set; }
       public double Width { get; set; }
    
       public override double Area
       {
          get { return Math.Round(Length * Width,2); }
       }
    
       public override double Circumference
       {
          get { return (Length + Width) * 2; }
       }
    }
    
    public class Square : Rectangle
    {
       public Square(double side) : base(side, side)
       {
          Side = side;
       }
    
       public double Side { get; set; }
    }
    
    public class Example
    {
       public static void Main()
       {
          Shape sh = null;
          Shape[] shapes = { new Square(10), new Rectangle(5, 7),
                             new Rectangle(10, 10), sh, new Square(0) };
          foreach (var shape in shapes)
             ShowShapeInfo(shape);
       }
    
       private static void ShowShapeInfo(Object obj)
       {
          switch (obj)
          {
             case Shape shape when shape.Area == 0:
                Console.WriteLine($"The shape: {shape.GetType().Name} with no dimensions");
                break;
             case Square sq when sq.Area > 0:
                Console.WriteLine("Information about the square:");
                Console.WriteLine($"   Length of a side: {sq.Side}");
                Console.WriteLine($"   Area: {sq.Area}");
                break;
             case Rectangle r when r.Area > 0:
                Console.WriteLine("Information about the rectangle:");
                Console.WriteLine($"   Dimensions: {r.Length} x {r.Width}");
                Console.WriteLine($"   Area: {r.Area}");
                break;
             case Shape shape:
                Console.WriteLine($"A {shape.GetType().Name} shape");
                break;
             case null:
                Console.WriteLine($"The {nameof(obj)} variable is uninitialized.");
                break;
             default:
                Console.WriteLine($"The {nameof(obj)} variable does not represent a Shape.");
                break;
          }
       }
    }
    // The example displays the following output:
    //       Information about the square:
    //          Length of a side: 10
    //          Area: 100
    //       Information about the rectangle:
    //          Dimensions: 5 x 7
    //          Area: 35
    //       Information about the rectangle:
    //          Dimensions: 10 x 10
    //          Area: 100
    //       The obj variable is uninitialized.
    //       The shape: Square with no dimensions

    catch(  )  when  语句

    using System;
    using System.Net.Http;
    using System.Threading.Tasks;
    
    class Program
    {
        static void Main()
        {
            Console.WriteLine(MakeRequest().Result);
        }
    
        public static async Task<string> MakeRequest()
        {
            var client = new HttpClient();
            var streamTask = client.GetStringAsync("https://localHost:10000");
            try
            {
                var responseText = await streamTask;
                return responseText;
            }
            catch (HttpRequestException e) when (e.Message.Contains("301"))
            {
                return "Site Moved";
            }
            catch (HttpRequestException e) when (e.Message.Contains("404"))
            {
                return "Page Not Found";
            }
            catch (HttpRequestException e)
            {
                return e.Message;
            }
        }
    }

    5.表达式主体定义

    public override string ToString() => $"{fname} {lname}".Trim();
    //等效于
    public override string ToString()
    {
       return $"{fname} {lname}".Trim();
    }

    6. $ 特殊字符将字符串文本标识为内插字符串

    string name = "Mark";
    var date = DateTime.Now;
    
    // Composite formatting:
    Console.WriteLine("Hello, {0}! Today is {1}, it's {2:HH:mm} now.", name, date.DayOfWeek, date);
    // String interpolation:
    Console.WriteLine($"Hello, {name}! Today is {date.DayOfWeek}, it's {date:HH:mm} now.");
    // Both calls produce the same output that is similar to:
    // Hello, Mark! Today is Wednesday, it's 19:40 now.

    C#7:

    1.元组(Tuple)

    (string Alpha, string Beta) namedLetters = ("a", "b");
    Console.WriteLine($"{namedLetters.Alpha}, {namedLetters.Beta}");

    或者变量声明用var

    var alphabetStart = (Alpha: "a", Beta: "b");
    Console.WriteLine($"{alphabetStart.Alpha}, {alphabetStart.Beta}");

    构造函数中有Deconstruct,在生成对象时,可以提取你需要的属性值

    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);
    }
    
    var p = new Point(3.14, 2.71);
    (double X, double Y) = p;

    弃元

    当提取出来的数据不需要时,用‘_’占位符号,来放弃当前的变量

    using System;
    using System.Collections.Generic;
    
    public class Example
    {
        public static void Main()
        {
            var (_, _, _, pop1, _, pop2) = QueryCityDataForYears("New York City", 1960, 2010);
    
            Console.WriteLine($"Population change, 1960 to 2010: {pop2 - pop1:N0}");
        }
    
        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);
        }
    }
    // The example displays the following output:
    //      Population change, 1960 to 2010: 393,149

    is 运算符添加了一些功能,如下,如果input可以转换为int类型,就把转换后的值赋值给count.

    if (input is int count)
        sum += count;

    switch( )增加了一些新功能

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

    async main,main方法前面可以添加async修饰符号

    static int Main()
    {
        return DoAsyncWork().GetAwaiter().GetResult();
    }
    可以写成下面
    static async Task<int> Main()
    {
        // This could also be replaced with the body
        // DoAsyncWork, including its await expressions:
        return await DoAsyncWork();
    }
    如果没有返回证人数字,可以返回一个task
    static async Task Main()
    {
        await SomeAsyncMethod();
    }

    本地函数

    public static IEnumerable<char> AlphabetSubset3(char start, char end)
    {
        if (start < 'a' || start > 'z')
            throw new ArgumentOutOfRangeException(paramName: nameof(start), message: "start must be a letter");
        if (end < 'a' || end > 'z')
            throw new ArgumentOutOfRangeException(paramName: nameof(end), message: "end must be a letter");
    
        if (end <= start)
            throw new ArgumentException($"{nameof(end)} must be greater than {nameof(start)}");
    
        return alphabetSubsetImplementation();
    
        IEnumerable<char> alphabetSubsetImplementation()
        {
            for (var c = start; c < end; c++)
                yield return c;
        }
    }

    throw表达式

    private static void DisplayFirstNumber(string[] args)
    {
       string arg = args.Length >= 1 ? args[0] :
                                  throw new ArgumentException("You must supply an argument");
       if (Int64.TryParse(arg, out var number))
          Console.WriteLine($"You entered {number:F0}");
       else
          Console.WriteLine($"{arg} is not a number.");
    }

    默认文本表达式

    Func<string, bool> whereClause = default(Func<string, bool>);
    可以写成这样
    Func<string, bool> whereClause = default;

    C#4中有了命名参数,C#7.2中方法的命名参数只要和参数的默认顺序相同,也是可以不写出参数名称的

    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(sellerName: "Gift Shop", 31, productName: "Red Mug");
    // This generates CS1738: Named argument specifications must appear after all fixed arguments have been specified.
    PrintOrderDetails(productName: "Red Mug", 31, "Gift Shop");

    in 参数修饰符,表明该参数被作为引用类型来传递,且不能被方法修改

    static void M(S arg);
    static void M(in S arg);

    C#8:

    switch语句的升级

    public static RGBColor FromRainbow(Rainbow colorBand) =>
        colorBand switch
        {
            Rainbow.Red    => new RGBColor(0xFF, 0x00, 0x00),
            Rainbow.Orange => new RGBColor(0xFF, 0x7F, 0x00),
            Rainbow.Yellow => new RGBColor(0xFF, 0xFF, 0x00),
            Rainbow.Green  => new RGBColor(0x00, 0xFF, 0x00),
            Rainbow.Blue   => new RGBColor(0x00, 0x00, 0xFF),
            Rainbow.Indigo => new RGBColor(0x4B, 0x00, 0x82),
            Rainbow.Violet => new RGBColor(0x94, 0x00, 0xD3),
            _              => throw new ArgumentException(message: "invalid enum value", paramName: nameof(colorBand)),
        };
    
    和下面的一样的功能
    public static RGBColor FromRainbowClassic(Rainbow colorBand)
    {
        switch (colorBand)
        {
            case Rainbow.Red:
                return new RGBColor(0xFF, 0x00, 0x00);
            case Rainbow.Orange:
                return new RGBColor(0xFF, 0x7F, 0x00);
            case Rainbow.Yellow:
                return new RGBColor(0xFF, 0xFF, 0x00);
            case Rainbow.Green:
                return new RGBColor(0x00, 0xFF, 0x00);
            case Rainbow.Blue:
                return new RGBColor(0x00, 0x00, 0xFF);
            case Rainbow.Indigo:
                return new RGBColor(0x4B, 0x00, 0x82);
            case Rainbow.Violet:
                return new RGBColor(0x94, 0x00, 0xD3);
            default:
                throw new ArgumentException(message: "invalid enum value", paramName: nameof(colorBand));
        };
    }
    public static string RockPaperScissors(string first, string second)
        => (first, second) switch
        {
            ("rock", "paper") => "rock is covered by paper. Paper wins.",
            ("rock", "scissors") => "rock breaks scissors. Rock wins.",
            ("paper", "rock") => "paper covers rock. Paper wins.",
            ("paper", "scissors") => "paper is cut by scissors. Scissors wins.",
            ("scissors", "rock") => "scissors is broken by rock. Rock wins.",
            ("scissors", "paper") => "scissors cuts paper. Scissors wins.",
            (_, _) => "tie"
        };

    using语句,在作用于的结尾,对象会被销毁

    static int WriteLinesToFile(IEnumerable<string> lines)
    {
        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
    }
    以前的写法需要把using语句写在小括号里

    static int WriteLinesToFile(IEnumerable<string> lines)
    {
    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++;
    }
    }
    return skippedLines;
    } // file is disposed here
    }

    引用类型也可为空,类似于可为空的值类型int?,string?

    数组的索引和范围

    var words = new string[]
    {
                    // index from start    index from end
        "The",      // 0                   ^9
        "quick",    // 1                   ^8
        "brown",    // 2                   ^7
        "fox",      // 3                   ^6
        "jumped",   // 4                   ^5
        "over",     // 5                   ^4
        "the",      // 6                   ^3
        "lazy",     // 7                   ^2
        "dog"       // 8                   ^1
    };              // 9 (or words.Length) ^0
    
    Console.WriteLine($"The last word is {words[^1]}");
    // writes "dog"
    
    var quickBrownFox = words[1..4]; 从第二个到第5个
    
    var lazyDog = words[^2..^0]; //从倒数第3个到倒数第一个
    
    var allWords = words[..]; // contains "The" through "dog".
    var firstPhrase = words[..4]; // contains "The" through "fox"
    var lastPhrase = words[6..]; // contains "the", "lazy" and "dog"
    
    Range phrase = 1..4;
    var text = words[phrase];

    ??=操作符,只有左边为null时,才把??=右边的值赋值给左边

    List<int> numbers = null;
    int? i = null;
    
    numbers ??= new List<int>();
    numbers.Add(i ??= 17);
    numbers.Add(i ??= 20);
    
    Console.WriteLine(string.Join(" ", numbers));  // output: 17 17
    Console.WriteLine(i);  // output: 17

    处理字符串的$ 和 @可以嵌套使用,例如$@"..."

    C#9

    使用new生成对象时,可以不写类型

    private List<WeatherObservation> _observations = new();

    判断条件的优化

    public static bool IsLetter(this char c) =>
        c is >= 'a' and <= 'z' or >= 'A' and <= 'Z';

    public static bool IsLetterOrSeparator(this char c) =>
    c is (>= 'a' and <= 'z') or (>= 'A' and <= 'Z') or '.' or ',';

    if (e is not null)
    {
    // ...
    }

  • 相关阅读:
    004-spring cache-声明性的基于XML的缓存
    003-spring cache-JCache (JSR-107) annotations
    002-spring cache 基于注解的缓存-02详细-Cacheable 、CachePut、CacheEvict、Caching、CacheConfig、EnableCaching、自定义
    002-spring cache 基于注解的缓存-01-关键注解概述、spel、缓存Key 与 缓存解析器
    001-springboot cache 简介、基础使用
    tools-eclipse-004-UML图安装
    001-Spring的设计理念和整体架构
    java-信息安全(十八)java加密解密,签名等总结
    005-java的Annotation
    002-原始jpa以及基本加载过程,基本sql使用
  • 原文地址:https://www.cnblogs.com/kingsmart/p/14138186.html
Copyright © 2020-2023  润新知