zoukankan      html  css  js  c++  java
  • C# 语法糖

     语法糖:指计算机语言中添加的某种语法,这种语法对语言的功能并没有影响,但是更方便程序员使用。通常来说使用语法糖能够增加程序的可读性,从而减少程序代码出错的机会。

        它可以给我们带来方便,是一种便捷的写法,编译器会帮我们做转换;而且可以提高开发编码的效率,在性能上也不会带来损失。

    语法糖——它不甜吗

    它好甜呐☻☺

    $符号、对象初始值设定项、元组、Linq、Null检查符?.、可爱的var、扩展方法、yield关键字
    1.$符号【字符串插值C#6新特性】的用法
    $符号的作用相当于对String.format()的简化

    //使用Format的写法
    string str2 = string.Format("my name is {0},my age is {1}.", name, age);
    //使用$语法糖的写法
    string str3 = $"my name is {name},my age is {age}.";

    2. 对象初始值设定项 和 匿名对象 ,类型实例化的语法糖 

    利用对象初始值设定项语法,你可为构造函数指定参数或忽略参数(以及括号语法)

    //对象初始化器
    Person p = new Person {
    Name = "andy",
    Age = 24
    };
    //匿名对象
    var p2 = new { Name = "dimo", Age = 24 };
    Console.WriteLine(p.Name);
    Console.WriteLine(p2.Name);
    Cat cat = new Cat { Age = 10, Name = "Fluffy" };
    Cat sameCat = new Cat("Fluffy"){ Age = 10 };

    声明一个List并给list赋初始值——初始值设定项

    List<string> list = new List<string> {"def","OK"};

    3、元组

    //结构Struct
    public struct ValueTuple<T1, T2, T3>: IEquatable<ValueTuple>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable<ValueTuple>, IValueTupleInternal, ITuple
    //类class
    public class Tuple<T1> : IStructuralEquatable, IStructuralComparable, IComparable, ITupleInternal, ITuple

    数组合并了相同类型的对象,而元组合并了不同类型的对象。

    ValueTuple<int,int> s = (1, 3);//直接使用()声明最方便
    var svar = (1, 3);//括号声明。
    Tuple<int> ne = new Tuple<int>(2);//new 或静态方法Create
    Tuple<int> creat = Tuple.Create<int>(2);//静态方法Create

    4. 集合类各个项的操作Linq。

    我们为了逐个处理集合中的项,需要这么写:

    foreach (string item in list)
    {
    Console.WriteLine(item);
    }

    现在不需要了,这样就可以了

    list.ForEach(a => Console.WriteLine(a));

    在语法糖的光辉照耀下,可以这样:Linq 或 对应方法。

    public class Program
    {
    public static void Main()
    {
    List<string> Sizes = new List<string> { "L", "XL", "XXL" };
    Sizes.ForEach(x => Console.WriteLine(x));
    
    
    //更多使用方法(包括但不限于这些 ,自己挖吧,伙伴们!):
    
    //确定“XL”是否在集合中
    var r1 = Sizes.Contains("XL");
    
    //确定集合中是否包含与条件匹配的元素
    var r2 = Sizes.Exists(x => x == "XL");
    
    //返回集合项中包含“X”的第一个元素
    var r3 = Sizes.Find(x => x.Contains("X"));
    }
    }

    5.??、 ?、 ?: 、?.
    1. 可空类型修饰符(?)
    2. 三元(运算符)表达式(?: )
    例如:x?y:z 表示如果表达式x为true,则返回y;
    如果x为false,则返回z,是省略if{}else{}的简单形式。
    3. 空合并运算符(??)——相当于三目运算符,
    判断是否不为空 x??y 相当于 x!=null?x:y

    最大的用处是将可空类型的值赋给对应的基元类型进行简化。可空类型不可强转对应C#内置类型。

    int? i = 123;
    
    int j = i ?? 0;

    4.NULL检查运算符(?.) 替代原来的 .

    ?[]是索引器的Null检查用法。

    如果 a 的计算结果为 null,则 a?.x 或 a?[x] 的结果为 null。

    如果 a 的计算结果为非 null,则 a?.x 或 a?[x] 的结果将分别与 a.x 或 a[x] 的结果相同。

    int? firstX = null;
    if (points != null)
    {
      var first = points.FirstOrDefault();
      if (first != null)
      firstX = first.X;
    }

    正确倒是正确了,代码取变得难读多了。在C# 6.0中,引入了一个 ?. 的运算符,前面的代码可以改成如下形式:
    int? firstX = points?.FirstOrDefault()?.X;
    从这个例子中我们也可以看出它的基本用法:如果对象为NULL,则不进行后面的获取成员的运算,直接返回NULL
    6. 可爱的var

    var的意义时不必写声明的类型,编译器会根据后面对var的赋值判断它的类型,var的类型一旦确认就不能再改变,它只能作为局部变量使用,不能用做字段也不能用做参数声明。

    例如:

    var writer = new StreamWriter(path);
    
    for(var i=0;i<100;i++){}

    7. 传说中的扩展方法
    1、 扩展类必须为静态类,扩展方法必须为静态方法【静态类中只能有静态方法】
    2、扩展方法的第1个形参开头必须使用 “this” 关键字然后再填写扩展的目标类。
    3、如果需要接收参数则从第2个参数开始算起,第1个参数在真正调用方法时是隐藏的。

    在c#3.5时引入了扩展方法,我们可以在不修改类源码的情况下给类增加实例方法,这个很有意义。它的实质也是一种语法糖的实现

    例如我们给String类扩展一个IsNumber的方法:

    public static class StringExt {
    static private Regex regexNumber = new Regex("\d+");
    static public bool IsNumber(this string input)
    {
    if (string.IsNullOrEmpty(input))
    {
    return false;
    }
    return regexNumber.IsMatch(input);
    }
    }

     扩展方法有两种调用方式

    扩展方法:

    public static class ItemsManagerComponentHelper
    {
    
    public static ItemInfo getItemById(this ItemsManagerComponent self, long itemId)

    调用:

    ItemInfo newFashion0 = ItemsManagerComponentHelper.getItemById(itemsManagerComponent,10);
    ItemInfo newFashion = itemsManagerComponent.getItemById(10);

    ————————————————

    参考链接:https://blog.csdn.net/kone0611/article/details/76056318

    ▲在 java 中没有这样的东西,一个类一旦是 final 的 ,这个类就不能再被添加方法, 但是 C# 能够做到,可以给 sealed 类添加新的方法,这点我还是比较喜欢 c# 的。这就是 C# 中的扩展方法。
    那么什么情况下我们才需要去给一个类写扩展方法呢?
    系统自带的类型,我们无法去修改;
    修改源代码需要较大的精力,而且可能会带来错误;
    我们只是需要一个或者较少的几个方法,修改源代码费时费力;
    被扩展的类是 sealed 的,不能被继承;(就算不是 sealed 的,我们也不能因为需要一个方法而去写一个子类,这样不是面向对象)
    ▲下面是扩展方法的三个要素:(也算是语法规则)
    扩展方法必须处于一个静态类中;
    扩展方法必须是一个静态方法;
    扩展方法的参数列表必须以 this 开头,this 后面紧跟的是被扩展类,然后才是方法需要的参数;
    ▲下面写一下扩展方法的特点
    this 关键字紧跟着的不是参数,而是调用者,调用者后面的参数才是扩展方法真正的参数,在调用时必须传递;
    如果被扩展的类中的实例方法和扩展方法的方法签名相同(扩展方法中方法的签名应该要去掉 this 和调用者参数),则优先调用本类中的实例方法;
    被扩展类(可以是普通类,也可以是接口抽象类)的子类对象可以直接调用父类的扩展方法,也就是说子类也继承了父类的扩展方法;
    这点算是第 3 点的补充,只有被扩展类的本类对象或者子类对象,才能调用扩展方法;
    8. yield关键字定义迭代器方法,返回值必须是IEnumberable等集合接口
    yield return:
    先看下面的代码,通过yield return实现了类似用foreach遍历数组的功能,说明yield return也是用来实现迭代器的功能的。执行完第一个yield再向下执行。

    using static System.Console;
    using System.Collections.Generic;
    class Program
    {
        //一个返回类型为IEnumerable<int>,其中包含三个yield return
        //yield return 定义迭代器方法。
        public static IEnumerable<int> enumerableFuc()
        {
            yield return 1;
            yield return 2;
            yield return 3;
        }
    
        static void Main(string[] args)
        {
            //通过foreach循环迭代此函数
            foreach(int item in enumerableFuc())
            {
                WriteLine(item);
            }
            ReadKey();
        }
    }
    输出结果:
    1
    2
    3

    yield break是用来终止迭代的。
    2.只能使用在返回类型必须为 IEnumerable、IEnumerable<T>、IEnumerator 或 IEnumerator<T>的方法、运算符、get访问器中。
    这也能说明yield关键字其实是一种语法糖,最终还是通过实现IEnumberable<T>、IEnumberable、IEnumberator<T>和IEnumberator接口实现的迭代功能。

    3.编译的时候自动生成了一个新的类,方法返回了这个新的类。它继承了IEnumerable、IEnumerable<T>、IEnumerator 或 IEnumerator<T>,这时我们应该已经能猜到这个新的类就是我们没有实现对应的IEnumerator的MoveNext(),和Current属性,但是我们仍然能正常使用这些函数的原因了。

    源码,是痛苦的,又是快乐的,如果没有这痛苦,也就没有了这快乐!
  • 相关阅读:
    一张图片入门Python
    4.1. 如何在Windows环境下开发Python
    你必须知道的EF知识和经验
    XUnit的使用
    如何使用NUnit
    Entity Framework 不支持DefaultValue
    Have You Ever Wondered About the Difference Between NOT NULL and DEFAULT?
    Validation failed for one or more entities. See 'EntityValidationErrors' property for more details
    Entity Framework 与多线程
    sqlite中的自增主键
  • 原文地址:https://www.cnblogs.com/erlongxizhu-03/p/12564175.html
Copyright © 2011-2022 走看看