1. 程式人生 > >C# 語法新特性

C# 語法新特性

C# 語法新特性

下面介紹下C#的新語法,這些新語法使程式設計更方便快捷(往往一行程式碼能起到老語法幾行功能),同時也更健壯減少異常發生,方便閱讀。個人認為很有必要掌握下。

環境準備

新建一個Product類 和 ShoppingCart

    public class Product
    {
        public string Name { get; set; }
        public string Category { get; set; } = "Waterports";
        public decimal? Price { get; set; }
        public Product Related { get; set; }
        public bool InStock { get; } = true;
        public bool NameBeginsWithS => Name?[0] == 'S';

        public static Product[] GetProduct()
        {
            Product kayak = new Product
            {
                Name = "Kayak",
                Category="Water Craft",
                Price = 275M
            };
            Product lifejacket = new Product
            {
                Name = "Lifejacket",
                Price = 48.95M
            };

            kayak.Related = lifejacket;


            return new Product[] { kayak, lifejacket, null };
        }
    }

    public class ShoppingCart:IEnumerable<Product>
    {
        public IEnumerable<Product> Products { get; set; }

        public IEnumerator<Product> GetEnumerator()
        {
            return Products.GetEnumerator();
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }
    }

新語法介紹

  1. null 條件符(?) 語義:只有當物件不為null時才訪問物件屬性
    ```
    public ViewResult Index()
    {
    List

             results.Add(string.Format($"Name:{name},Price{price},Related:{relatedName}"));
         }
         return View(results);
     }
    ```
  2. null 合併符(??) 語義:當??操作符左側為null則返回右側值,否則放回左側。
    decimal? price = p?.Price ?? 0;
  3. 屬性設定初始值,在宣告屬性時可以為屬性設定初始值
    public string Category { get; set; } = "Waterports";

  4. 設定read-only屬性初始值(有兩種方法,另一種在建構函式中設定)
    public bool InStock { get; } = true;
  5. 字串中插入變數值,這種時字串拼接更簡單,格式$+字串
    $"Name:{name},Price{price},Related:{relatedName}"
  6. 物件和集合的初始化
    //物件初始化 Product kayak = new Product { Name = "Kayak",Category="Water Craft",Price = 275M }; //陣列類初始化 string[] names = new string[] { "Bob", "Joe", "Alice" }; //字典初始化 Dictionary<string, Product> products = new Dictionary<string, Product> { ["Kayak"]=new Product { Name = "Kayak",Category = "Water Craft"}, ["Lifejacket"]=new Product { Name = "Lifejacket", Category = "Water Craft" } };

  7. 型別檢測符(is) 分析if(data[i] is decimal d)如果data[i]的型別是decimal則返回true並給d變數賦值,在switch語句中同樣可以使用
    public ViewResult Total() { object[] data = new object[] { 275M, 29.95, "apple", "orange", 100, 10 }; decimal total = 0; for(int i = 0; i < data.Length; i++) { if(data[i] is decimal d) { total += d; } } return View($"Total:{total:C2}"); }
  8. 擴充套件方法,通過擴充套件方法為現有型別新增方法,使呼叫更方便(注意:1.類為靜態類,2方法為靜方法 3.第一個引數 this 被擴充套件型別)
    public static class ShoppingCartExtension { public static decimal TotalPrices(this ShoppingCart cartParam) { decimal total = 0; foreach(Product prod in cartParam.Products) { total += prod?.Price ?? 0; } return total; } }
  9. 應用介面的擴充套件方法,(建議最好建立介面的擴充套件方法可以複用)
    ```
    public static class ShoppingCartExtension
    {
    public static decimal TotalPrices(this IEnumerable

             return total;
         }
     }
    ```
  10. 使用Lambde表示式表達條件,這樣呼叫端更靈活

        public static class ShoppingCartExtension
        {
            //過濾表示式
            public static IEnumerable<Product> Filter(this IEnumerable<Product> productEnum, Func<Product, bool> selector)
            {
                foreach (Product prod in productEnum)
                {
                    if (selector(prod))
                    {
                        yield return prod;
                    }
                }
            }
        }
    

    呼叫更靈活

    //根據name過濾
    IEnumerable<Product> ProductsbyName =Product.GetProduct().Filter(p => p?.Name?[0] == 'S');
    //或者根據價格過濾
    IEnumerable<Product> ProductsbyPrice =Product.GetProduct().Filter(p => (p?.Price ?? 0) > 30);
  11. Lambda初始化屬性或函式

    //初始化屬性
    public bool NameBeginsWithS => Name?[0] == 'S';
    //初始化函式
    public ViewResult ProductsName() => View(Product.GetProduct().Select(p => p?.Name));
  12. 非同步呼叫asyncawait

            public async static Task<long?> GetPageLength2()
            {
                HttpClient client = new HttpClient();
                var httpMessage = await client.GetAsync("https://baidu.com");
    
                return httpMessage.Content.Headers.ContentLength;
            }

    在呼叫該方法

            public async Task<ViewResult> GetPageLength()
            {
                long? length = await AsyncMethods.GetPageLength2();
                return View($"Length:{length}");
            }
  13. nameof()獲取表示式的變數的字串形式(為當前變數名新增雙引號""),這樣避免hard code忘了更新。

        public ViewResult Products()
            {
                var products = new[] {
                    new {Name="Kayak",Price=275M},
                    new {Name="Lifejacket",Price=48.95M},
                    new {Name="Soccer ball",Price=19.50M},
                    new {Name="Corner flag",Price=34.95M},
                };
                //return View(products.Select(p => $"Name:{p.Name},{Price:{p.Price}"));
                //同上 避免更改了屬性名忘記更改 hard code`Name`和`Price`
                return View(products.Select(p => $"{nameof(p.Name)}:{p.Name},{nameof(p.Price)}:{p.Price}"));
            }