zoukankan      html  css  js  c++  java
  • 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();
    		}
    	}
    

    新语法介绍

    • null 条件符(?) 语义:只有当对象不为null时才访问对象属性
        public HomeController
        {
            public ViewResult Index()
            {
                List<string> results = new List<string>();
                foreach (Product p in Product.GetProduct())
                {
                    string name = p?.Name ?? "<No Name>";
                    decimal? price = p?.Price ?? 0;
                    string relatedName = p?.Related?.Name ?? "<None>";
                    results.Add(string.Format($"Name:{name},Price{price},Related:{relatedName}"));
                }
                return View(results); 
            }
        }
    
    • null 合并符(??) 语义:当??操作符左侧为null则返回右侧值,否则放回左侧。
        decimal? price = p?.Price ?? 0;
    
    • 属性设置初始值,在声明属性时可以为属性设置初始值
        public string Category { get; set; } = "Waterports";
    
    • 设置read-only属性初始值(有两种方法,另一种在构造函数中设置)
        public bool InStock { get; } = true;
    
    • 字符串中插入变量值,这种时字符串拼接更简单,格式$+字符串
        $"Name:{name},Price{price},Related:{relatedName}"
    
    • 对象和集合的初始化
            //对象初始化  
            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" }
            };
    
    • 类型检测符(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}");
            }
    
    • 扩展方法,通过扩展方法为现有类型添加方法,使调用更方便(注意: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;
            }
        }
    
    • 应用接口的扩展方法,(建议最好创建接口的扩展方法可以复用)
        public static class ShoppingCartExtension
        {
            public static decimal TotalPrices(this IEnumerable<Product> products)
            {
                decimal total = 0;
                foreach (Product prod in products)
                {
                    total += prod?.Price ?? 0;
                }
                return total;
            }
        }
    
    
    • 使用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);
    
    • Lambda初始化属性或函数
        //初始化属性
        public bool NameBeginsWithS => Name?[0] == 'S';
        //初始化函数
        public ViewResult ProductsName() => View(Product.GetProduct().Select(p => p?.Name));
    
    • 异步调用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}");
            }
    
    • 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}"));
            }
    
  • 相关阅读:
    108. Convert Sorted Array to Binary Search Tree
    107. Binary Tree Level Order Traversal II
    106. Construct Binary Tree from Inorder and Postorder Traversal
    105. Construct Binary Tree from Preorder and Inorder Traversal
    104. Maximum Depth of Binary Tree
    103. Binary Tree Zigzag Level Order Traversal
    102. Binary Tree Level Order Traversal
    系统和进程相关信息
    文件I/0缓冲
    系统编程概念(文件系统mount等函数的使用)
  • 原文地址:https://www.cnblogs.com/LoveTomato/p/9923134.html
Copyright © 2011-2022 走看看