(一)顶级语句(C# 9)
顶级语句是学的python这样的语言,如果是简单的控制台程序,就可以不用写命名空间、类、Main函数了,直接可以写代码。
1。直接在C# 文件中编写入口方法的代码,不用类,不用Main。经典写法仍然是支持的。反编译一下可以了解到真相
2。同一个项目中只能有一个文件具有顶级语句。
3。 顶级语句中可以直接使用await语法,也可以声明函数
Console.WriteLine($"Hello, World! {cal(1,2)}");
await File.ReadAllTextAsync("d:\\1.txt");
Console.ReadKey();
static int cal(int a,int b)
{
return a + b;
}4。using还是可以使用的。
把ConsoleApp1.dll拖至ILSpy窗口(注意使用8.0以上版本,否则不认识新版本c#),可以查看到反编译的结果。
可以看到类与Main函数还是有的,顶级语句编译器还是会帮助生成这些。

(二)全局Using语句(C#10)
1。将global修饰符添加到using前,这个命名空间就应用到整个项目,不用重复using.
只要你的项目中有一个文件做了global修饰,这个项目中其它全部文件就不用再重复引用这个using了。
2。通常创建一个专门用来编写全局using代码的C# 文件,类似下图:

3。如果csproj中启用了 <ImplicitUsings>enable</ImplicitUsings>,
编译器会自动隐式增加对System、System.Linq等常用命名空间的引用,不同各类型项目自动引入的命名空间也不一样。
(三)新的using声明(C# 8)
C#中,实现了IDisposible接口的对象可以使用using进行管理。
但是如果一段代码中很多托管资源需要被释放的话,代码中就会存在多个嵌套的using语句。

现在C#又嫌上面的写法太麻烦,增加了一种新方式:
在实现了IDisposable/IAsyncDisposable接口的类型变量声明前加上using,
当代码执行离开变量的作用域时,对象就会被释放。
还是上面图片的例子,现在可以这样:
当离openlib函数的作用域时,下面代码中的对象就会自动释放。
void openlib()
{
using SqlConnection conn=new SqlConnection("");
conn.Open();
using SqlCommand cmd=conn.CreateCommand();
cmd.CommandText="select * from T_articles";
using SqlDataReader reader=cmd.ExecuteReader();
while(reader.Read())
{
string title=reader.GetString(reader.GetOrdinal("Title"));
Console.WriteLine(title);
}
}
关于变量作用域,请再看下面的例子:
这里对象f1会被释放两次,因为它的作用域是在{} 之间。

一个坑:
见下面代码。
using var outStream=File.OpenWrite("e:/1.txt");
using var writer=new StreamWriter(outStream);
writer.WriteLine("hello");
string s=File.ReadAllText("e:/1.txt");
Console.WriteLine(s);这段代码会产生下面的异常。
原因:outStream和writer还没脱离作用域,所以还没被释放,直到运行到第四句话,报“文件被占用的错误”

解决方法:
加个大括号,定义一个作用域即可。
当然你也可以使用旧的using方式。
{
using var outStream = File.OpenWrite("m:/1.txt");
using var writer = new StreamWriter(outStream);
writer.WriteLine("hello");
}
string s = File.ReadAllText("m:/1.txt");
Console.WriteLine(s);
Console.ReadKey();(四)namespace和它下面的类可以是平级关系
我们定义一个类,原有方式是这样的。
表示 Class1是属于ConsoleApp1命名空间下的。
namespace ConsoleApp1
{
internal class Class1
{
}
}现在可以写成这样:
namespace ConsoleApp1;
internal class Class1
{
}这种新写法只是去掉了大括号,你用Class1的时候,还是要写成ConsoleApp1.Class1


少有人走的路


















