24.特殊语法

24.特殊语法


24.1 知识点

var隐式类型

  • var是一种特殊的变量类型 它可以用来表示任意类型的变量
  • 注意:
    1. var不能作为类的成员,只能用于临时变量声明时,一般写在函数语句块中
    2. var必须初始化,而且初始化后的变量不可以直接更改成别的类型
    3. 在不确定类型的时候可以用于装载对象
    4. 偷懒,变量类型可以写少点
// 实例
var i = 5; // var必须初始化
// i = "123"; // 报错,初始化完的变量不可以直接更改成别的类型
var s = "123";
var array = new int[] { 1, 2, 3, 4 };
var list = new List<int>();

申明对象时设置对象初始值

  • 申明对象时,可以通过直接写大括号的形式初始化公共成员变量和属性

class语句块外 namespace语句块内

// 人类 用于测试
class Person
{
    public int money;
    public bool sex;

    public int Age { get; set; }

    public Person() { }

    public Person(int money)
    {
        this.money = money;
    }
}

主函数内

// 实例
Person person1 = new Person(); // 传统无参构造
Person person2 = new Person(250); // 传统有参构造
Person person3 = new Person { sex = true, Age = 18, Name = "韬老狮" }; // 直接写大括号实例化 并且大括号内把公共的成员初始化了(实际上无参构造函数还是调用了的)
Person person4 = new Person() { sex = true, Age = 18, Name = "韬老狮" }; // 调用无参构造实例化 并且大括号内把公共的成员初始化了
Person person5 = new Person(666) { Age = 18 }; // 调用有参构造实例化 初始化money的值666 并且大括号内把公共的成员初始化了 但是大括号内没有初始化money
Console.WriteLine("person5.money = " + person5.money); // person5.money = 666
Person person6 = new Person(666) { Age = 18, money = 999 }; // 调用有参构造实例化 初始化money的值666 并且大括号内把公共的成员初始化了 大括号内初始化了money
// 注意:大括号的初始化是后赋值的 666是先传入有参构造函数初始化money的 但是大括号初始化时money又被赋值999了 所以person5.money的值是999
Console.WriteLine("person6.money = " + person6.money); // person6.money = 999

申明集合对象时设置集合初始值

  • 申明集合对象时,也可以通过大括号直接初始化内部属性

主函数内

// 实例
int[] array2 = new int[] { 1, 2, 3, 4, 5 }; // 数组声明时直接赋值几个元素
List<int> listInt = new List<int>() { 1, 2, 3, 4, 5, 6 }; // List声明时也可以直接赋值几个元素
List<Person> listPerson = new List<Person>() {
    new Person(200),
    new Person(100){Age = 10},
    new Person(1){sex = true, Name = "韬老狮"}
};
Dictionary<int, string> dic = new Dictionary<int, string>()
{
    { 1, "123" },
    { 2, "222"}
}; // Dictionary声明时也可以直接赋值几个元素

匿名类型

  • var变量可以声明为自定义的匿名类型
  • 基本语法:var obj = new { 成员变量1 = xx, 成员变量2 = xx, ... 成员变量n = xx };

主函数内

// 实例
var v = new { age = 10, money = 11, name = "小明" }; // 可以说实例化了一个匿名类型的数据集合
Console.WriteLine("v.age:" + v.age); // v.age:10
Console.WriteLine("v.name:" + v.name); // v.name:小明
// 注意:匿名类型只能包含成员变量,不能包含成员函数等
// var v2 = new { fun = () => { } }; // 报错,无法将lambda表达式分配给匿名类型属性

可空类型

值类型是不能赋值为空的

// int c1 = null; // 报错

值类型申明时,在值类型后面加? 可以赋值为空,这样值类型就变成可空类型了

//实例
int? c1 = null;//声明int可空类型的值为null 不会报错 可以理解为在栈上分配了房间 里面是空房间
int? c2 = 3;//声明int可空类型的值为3 不会报错

//加了?后的变量类型:
//int? 就代表 c1和c2的类型 已结不是Int32结构体了 而是Nullable<T>可空类型泛型结构体
//Nullable<T>可空类型泛型结构体中的T就是什么跟着问号 什么就是T 比如int?类型其实就是Nullable<int>

//其他类型变成对应的泛型可空类型也没问题
float? floatValue = null;
double? doubleValue = null;

//注意:引用类型后面加?转成可空类型 也不会报错 只是引用类型本来就可空 所以没必要
object? objValue = null;

调用Nullable可空类型泛型结构体中的HasValue方法,判断可空类型是否为空

//c1为空 进不去if语句
if (c1.HasValue)
{
    //直接打印 其实是打印可空类型的ToString()方法
    Console.WriteLine("c1:" + c1);
    //Nullable<T> 可空类型泛型结构体中有Value属性存储值
    Console.WriteLine("c1.Value:" + c1.Value);
}

//c2不为空 进入if语句类的逻辑
if (c2.HasValue)
{
    //直接打印 其实是打印可空类型的ToString()方法
    Console.WriteLine("c2:" + c2);//c2: 3
    //Nullable<T> 可空类型泛型结构体中有Value属性存储值
    Console.WriteLine("c2.Value:" + c2.Value);//c2.Value:3
}

调用Nullable可空类型泛型结构体中的GetValueOrDefault方法,可以安全获取可空类型值

//声明可空类型的值为null
int? intValue = null;

//直接调用GetValueOrDefault方法
//如果intValue为空 返回返回值类型的默认值
Console.WriteLine("intValue.GetValueOrDefault():" + intValue.GetValueOrDefault());//intValue.GetValueOrDefault():0

//调用GetValueOrDefault方法 传入一个参数 参数是你先自己指定的默认值
//如果intValue为空 返回传入的指定的默认值
Console.WriteLine("intValue.GetValueOrDefault(100):" + intValue.GetValueOrDefault(100));//intValue.GetValueOrDefault(100):100

//注意:调用了GetValueOrDefault方法后 intValue的值并不会改变
//这个方法只是判断Nullable<T> 可空类型泛型结构体Value属性是否为空 不为空返回Value 为空就返回对应的默认值
Console.WriteLine("intValue:" + intValue);//intValue:

//重新赋值后再打印
intValue = 250;
Console.WriteLine("intValue:" + intValue);//intValue:250
Console.WriteLine("intValue.GetValueOrDefault():" + intValue.GetValueOrDefault());//intValue.GetValueOrDefault():250
Console.WriteLine("intValue.GetValueOrDefault(100):" + intValue.GetValueOrDefault(100));//intValue.GetValueOrDefault(100):250

可空类型 使用?判空后 再进行操作

//正常来说 假如调用一个可以为空的类型变量的ToString方法的时候要先判空 不为空再调用ToString方法 否则为空的话会报错
object objectValue = null;
if (objectValue != null)//判空
{
    Console.WriteLine(objectValue.ToString());//不为空再调用ToString方法
}

//现在学了可空类型之后 可空类型变量可以 后面跟着? 判断可空类型变量是否为空 再执行后面的操作 不为空则执行 为空则不执行
//基本语法:可空类型变量? 后面可以调用方法 索引器等
//相当于是一种语法糖 能够帮助我们自动去判断可空类型变量是否为空

//object类型是可空类型变量 后面跟着?判断objectValue是否为空 不为空则执行后面.出来的ToString方法 为空则不执行
Console.WriteLine("objectValue?.ToString():" + objectValue?.ToString());//objectValue?.ToString():

//数组也是可空类型变量 可以后面跟着?判断当前数组是否为空 不为空则执行后面的索引器 为空则不执行
int[] intArray = null;
Console.WriteLine("intArray?[1]:" + intArray?[1]);//intArray?[1]:

//委托也是可空类型变量 可以后面跟着?判断当前委托是否为空 不为空则执行后面.出来的Invoke方法 为空则不执行
//正常来说 假如执行委托的时候要先判空 不为空再执行委托 否则为空的话会报错
Action action = null;
if (action != null)
{
    action();
}
action?.Invoke();

空合并操作符

  • 空合并操作符 ??
  • 左边值 ?? 右边值
  • 如果左边值为null,就返回右边值,否则返回左边值
  • 只要是可以为null的类型都能用
  • 有点三目运算符简化版的感觉
// 声明int可空类型intV的值为null
int? intV = null;

// 三目运算符:如果intV为空,intI1赋值100,否则intV不为空,intI1赋值intV的值
int intI1 = intV == null ? 100 : intV.Value; // 这里不能直接返回intV,

因为intV现在是int可空类型
Console.WriteLine("intI1:" + intI1); // intI1:100

// 空合并操作符:如果intV为空,返回右边值100,否则intV不为空,返回左边值intV的值
int intI2 = intV ?? 100; // 这里可以直接返回intV,可以理解为??帮我们特殊处理了
Console.WriteLine("intI2:" + intI2); // intI2:100

// 声明引用类型str的值为null
string str = null;

// 空合并操作符:如果str为空,返回右边值hahaha,否则str不为空,返回左边值str的值
str = str ?? "hahaha";
Console.WriteLine("str:" + str); // str:hahaha

内插字符串

  • 关键符号:$
  • 用$来构造字符串,让字符串中可以拼接变量
// 实例
string name = "林文韬";
int age = 22;
Console.WriteLine($"{name}要好好学习,现在已经{age}岁了"); // 林文韬要好好学习,现在已经22岁了

单句逻辑简略写法

  • 当循环或者if语句中只有一句代码时,大括号可以省略
  • 注意:只有一句代码的时候才能省略
// 实例
if (true)
    Console.WriteLine("if语句只有一句代码"); // if语句只有一句代码

for (int j = 0; j < 5; j++)
    Console.WriteLine("for语句只有一句代码 j:" + j);
// for语句只有一句代码 j:0
// for语句只有一句代码 j:1
// for语句只有一句代码 j:2
// for语句只有一句代码 j:3
// for语句只有一句代码 j:4

int k = 0;
while (k < 5)
    Console.WriteLine("while语句只有一句代码 k:" + k++);
// while语句只有一句代码 k:0
// while语句只有一句代码 k:1
// while语句只有一句代码 k:2
// while语句只有一句代码 k:3
// while语句只有一句代码 k:4

人类里,成员属性单句逻辑简略写法

public string Name
{
    get => "林文韬";
    set => sex = true;
}

public int Add(int x, int y) => x + y;
public void Speak(string str) => Console.WriteLine(str);

24.2 知识点代码

using System;
using System.Collections.Generic;

namespace Lesson23_特殊语法
{
    //class语句块外 namespace语句块内

    #region 知识点二 申明对象时设置对象初始值

    //人类 用于测试
    class Person
    {
        public int money;
        public bool sex;

        public int Age
        {
            get;
            set;
        }

        public Person()
        {

        }

        public Person(int money)
        {
            this.money = money;
        }

        //人类里
        #region 知识点八 单句逻辑简略写法

        //成员属性单句逻辑简略写法
        public string Name
        {
            get => "林文韬";
            set => sex = true;
        }

        //成员方法单句逻辑简略写法
        public int Add(int x, int y) => x + y;
        public void Speak(string str) => Console.WriteLine(str);

        #endregion
    }

    #endregion

    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("特殊语法");

            //主函数内

            #region 知识点一 var隐式类型

            //var是一种特殊的变量类型
            //它可以用来表示任意类型的变量

            //注意:
            //1.var不能作为类的成员 只能用于临时变量申明时
            //  也就是 一般写在函数语句块中
            //2.var必须初始化 而且初始化完的变量不可以直接更改成别的类型
            //3.在不确定类型的时候可以用于装载对象
            //4.偷懒 变量类型可以写少点

            //实例
            var i = 5;//var必须初始化
            //i = "123";//报错 初始化完的变量不可以直接更改成别的类型
            var s = "123";
            var array = new int[] { 1, 2, 3, 4 };
            var list = new List<int>();

            #endregion

            #region 知识点二 申明对象时设置对象初始值

            //申明对象时 
            //可以通过直接写大括号的形式初始化公共成员变量和属性

            //实例
            Person person1 = new Person();//传统无参构造
            Person person2 = new Person(250);//传统有参构造
            Person person3 = new Person { sex = true, Age = 18, Name = "韬老狮" };//直接写大括号实例化 并且大括号内把公共的成员初始化了(实际上无参构造函数还是调用了的)
            Person person4 = new Person() { sex = true, Age = 18, Name = "韬老狮" };//调用无参构造实例化 并且大括号内把公共的成员初始化了
            Person person5 = new Person(666) { Age = 18 };//调用有参构造实例化 初始化money的值666 并且大括号内把公共的成员初始化了 但是大括号内没有初始化money
            Console.WriteLine("person5.money = " + person5.money);//person5.money = 666
            Person person6 = new Person(666) { Age = 18, money = 999 };//调用有参构造实例化 初始化money的值666 并且大括号内把公共的成员初始化了 大括号内初始化了money
            //注意:大括号的初始化是后赋值的 666是先传入有参构造函数初始化money的 但是大括号初始化时money又被赋值999了 所以person5.money的值是999
            Console.WriteLine("person6.money = " + person6.money);//person6.money = 999

            #endregion

            #region 知识点三 申明集合对象时设置集合初始值

            //申明集合对象时
            //也可以通过大括号 直接初始化内部属性

            //实例
            int[] array2 = new int[] { 1, 2, 3, 4, 5 };//数组声明时直接赋值几个元素
            List<int> listInt = new List<int>() { 1, 2, 3, 4, 5, 6 };//List声明时也可以直接赋值几个元素
            List<Person> listPerson = new List<Person>() {
                new Person(200),
                new Person(100){Age = 10},
                new Person(1){sex = true, Name = "韬老狮"}
            };
            Dictionary<int, string> dic = new Dictionary<int, string>()
            {
                { 1, "123" },
                { 2, "222"}
            };//Dictionary声明时也可以直接赋值几个元素

            #endregion

            #region 知识点四 匿名类型

            //var变量可以申明为自定义的匿名类型
            //基本语法:var obj = new { 成员变量1 = xx, 成员变量2 = xx, ... 成员变量n = xx };

            //实例
            var v = new { age = 10, money = 11, name = "小明" };//可以说实例化了一个匿名类型的数据集合
            Console.WriteLine("v.age:" + v.age);//v.age:10
            Console.WriteLine("v.name:" + v.name);//v.name:小明
            //注意:匿名类型只能包含成员变量 不能包含成员函数等
            //var v2 = new { fun = () => { } };//报错 无法将lambda表达式分配给匿名类型属性

            #endregion

            #region 知识点五 可空类型

            //1.值类型是不能赋值为 空的
            //int c1 = null;//报错

            //2.值类型申明时 在值类型后面加? 可以赋值为空 这样值类型就变成可空类型了

            //实例
            int? c1 = null;//声明int可空类型的值为null 不会报错 可以理解为在栈上分配了房间 里面是空房间
            int? c2 = 3;//声明int可空类型的值为3 不会报错

            //加了?后的变量类型:
            //int? 就代表 c1和c2的类型 已结不是Int32结构体了 而是Nullable<T>可空类型泛型结构体
            //Nullable<T>可空类型泛型结构体中的T就是什么跟着问号 什么就是T 比如int?类型其实就是Nullable<int>

            //其他类型变成对应的泛型可空类型也没问题
            float? floatValue = null;
            double? doubleValue = null;

            //注意:引用类型后面加?转成可空类型 也不会报错 只是引用类型本来就可空 所以没必要
            object? objValue = null;

            //3. 调用Nullable<T>可空类型泛型结构体中的HasValue方法 判断可空类型是否为空

            //c1为空 进不去if语句
            if (c1.HasValue)
            {
                //直接打印 其实是打印可空类型的ToString()方法
                Console.WriteLine("c1:" + c1);
                //Nullable<T> 可空类型泛型结构体中有Value属性存储值
                Console.WriteLine("c1.Value:" + c1.Value);
            }

            //c2不为空 进入if语句类的逻辑
            if (c2.HasValue)
            {
                //直接打印 其实是打印可空类型的ToString()方法
                Console.WriteLine("c2:" + c2);//c2: 3
                //Nullable<T> 可空类型泛型结构体中有Value属性存储值
                Console.WriteLine("c2.Value:" + c2.Value);//c2.Value:3
            }

            //4.调用Nullable<T>可空类型泛型结构体中的GetValueOrDefault方法 可以安全获取可空类型值

            //声明可空类型的值为null
            int? intValue = null;

            //直接调用GetValueOrDefault方法
            //如果intValue为空 返回返回值类型的默认值
            Console.WriteLine("intValue.GetValueOrDefault():" + intValue.GetValueOrDefault());//intValue.GetValueOrDefault():0

            //调用GetValueOrDefault方法 传入一个参数 参数是你先自己指定的默认值
            //如果intValue为空 返回传入的指定的默认值
            Console.WriteLine("intValue.GetValueOrDefault(100):" + intValue.GetValueOrDefault(100));//intValue.GetValueOrDefault(100):100

            //注意:调用了GetValueOrDefault方法后 intValue的值并不会改变
            //这个方法只是判断Nullable<T> 可空类型泛型结构体Value属性是否为空 不为空返回Value 为空就返回对应的默认值
            Console.WriteLine("intValue:" + intValue);//intValue:

            //重新赋值后再打印
            intValue = 250;
            Console.WriteLine("intValue:" + intValue);//intValue:250
            Console.WriteLine("intValue.GetValueOrDefault():" + intValue.GetValueOrDefault());//intValue.GetValueOrDefault():250
            Console.WriteLine("intValue.GetValueOrDefault(100):" + intValue.GetValueOrDefault(100));//intValue.GetValueOrDefault(100):250

            //5.可空类型 使用?判空后 再进行操作

            //正常来说 假如调用一个可以为空的类型变量的ToString方法的时候要先判空 不为空再调用ToString方法 否则为空的话会报错
            object objectValue = null;
            if (objectValue != null)//判空
            {
                Console.WriteLine(objectValue.ToString());//不为空再调用ToString方法
            }

            //现在学了可空类型之后 可空类型变量可以 后面跟着? 判断可空类型变量是否为空 再执行后面的操作 不为空则执行 为空则不执行
            //基本语法:可空类型变量? 后面可以调用方法 索引器等
            //相当于是一种语法糖 能够帮助我们自动去判断可空类型变量是否为空

            //object类型是可空类型变量 后面跟着?判断objectValue是否为空 不为空则执行后面.出来的ToString方法 为空则不执行
            Console.WriteLine("objectValue?.ToString():" + objectValue?.ToString());//objectValue?.ToString():

            //数组也是可空类型变量 可以后面跟着?判断当前数组是否为空 不为空则执行后面的索引器 为空则不执行
            int[] intArray = null;
            Console.WriteLine("intArray?[1]:" + intArray?[1]);//intArray?[1]:

            //委托也是可空类型变量 可以后面跟着?判断当前委托是否为空 不为空则执行后面.出来的Invoke方法 为空则不执行
            //正常来说 假如执行委托的时候要先判空 不为空再执行委托 否则为空的话会报错
            Action action = null;
            if (action != null)
            {
                action();
            }
            action?.Invoke();

            #endregion

            #region 知识点六 空合并操作符

            // 空合并操作符 ??
            // 左边值 ?? 右边值
            // 如果左边值为null 就返回右边值 否则返回左边值
            // 只要是可以为null的类型都能用
            // 有点三目运算符简化版的感觉

            //实例

            //声明int可空类型intV的值为null
            int? intV = null;

            //三目运算符 如果intV为空 intI1赋值100 否则intV不为空 intI1赋值intV的值
            int intI1 = intV == null ? 100 : intV.Value;//这里不能直接返回intV 因为intV现在是int可空类型
            Console.WriteLine("intI1:" + intI1);//intI1:100

            //空合并操作符 如果intV为空 返回右边值100 否则intV不为空 返回左边值intV的值
            int intI2 = intV ?? 100;//这里可以直接返回intV 可以理解为??帮我们特殊处理了
            Console.WriteLine("intI2:" + intI2);//intI2:100

            //声明可空类型str的值为null
            string str = null;

            //空合并操作符 如果str为空 返回右边值hahaha 否则str不为空 返回左边值str的值
            str = str ?? "hahaha";
            Console.WriteLine("str:" + str);//str:hahaha

            #endregion

            #region 知识点七 内插字符串

            //关键符号:$
            //用$来构造字符串,让字符串中可以拼接变量

            //实例
            string name = "林文韬";
            int age = 22;
            Console.WriteLine($"{name}要好好学习,现在已经{age}岁了");//林文韬要好好学习,现在已经22岁了

            #endregion

            #region 知识点八 单句逻辑简略写法

            //当循环或者if语句中只有 一句代码时 大括号可以省略
            //注意:只有一句代码的时候才能省略

            //实例
            if (true)
                Console.WriteLine("if语句只有一句代码");//if语句只有一句代码

            for (int j = 0; j < 5; j++)
                Console.WriteLine("for语句只有一句代码 j:" + j);
            //for语句只有一句代码 j:0
            //for语句只有一句代码 j:1
            //for语句只有一句代码 j:2
            //for语句只有一句代码 j:3
            //for语句只有一句代码 j:4

            int k = 0;
            while (k < 5)
                Console.WriteLine("while语句只有一句代码 k:" + k++);
            //while语句只有一句代码 k:0
            //while语句只有一句代码 k:1
            //while语句只有一句代码 k:2
            //while语句只有一句代码 k:3
            //while语句只有一句代码 k:4

            #endregion
        }
    }
}


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com

×

喜欢就点赞,疼爱就打赏