24.特殊语法
24.1 知识点
var隐式类型
- var是一种特殊的变量类型 它可以用来表示任意类型的变量
- 注意:
- var不能作为类的成员,只能用于临时变量声明时,一般写在函数语句块中
- var必须初始化,而且初始化后的变量不可以直接更改成别的类型
- 在不确定类型的时候可以用于装载对象
- 偷懒,变量类型可以写少点
// 实例
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
//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
//声明可空类型的值为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