using 关键字有几个用法
-
导入命名空间
在C#中,using
指令允许你在代码中使用命名空间中定义的类型,而无需指定该类型的完全限定命名空间。这样可以使代码更加简洁易读。以下是一个使用using
指令导入命名空间的例子:
// 导入System命名空间
using System;
// 导入System.Collections.Generic命名空间
using System.Collections.Generic;
// 导入System.Linq命名空间
using System.Linq;
// 导入System.Text命名空间
using System.Text;
// 导入System.Threading.Tasks命名空间
using System.Threading.Tasks;
在上面的代码中,我们导入了几个常用的命名空间,这样在代码的其他部分就可以直接使用这些命名空间中的类型,而不需要每次都写出完整的命名空间。
例如,我们可以直接使用List<T>
或StringBuilder
,而不需要写出System.Collections.Generic.List<T>
或System.Text.StringBuilder
。
在C# 10中,global using
指令允许你在项目的所有文件中自动使用特定的命名空间,而无需在每个文件中重复声明。这对于那些在几乎每个文件中都会用到的命名空间非常有用,比如System
或你自己的项目中常用的命名空间。
以下是一个global using
指令的例子:
// GlobalUsings.cs文件
global using System;
global using System.Collections.Generic;
global using MyProject.Models;
在上面的例子中,System
和System.Collections.Generic
命名空间以及项目中定义的MyProject.Models
命名空间将在整个项目的所有文件中可用,无需在每个文件中单独声明。
-
导入静态类型
在C#中,using static
指令允许你导入一个静态类的静态成员,这样你就可以在代码中直接使用这些成员,而不需要指定类名。这在你需要频繁使用某个静态类的多个静态成员时非常有用。
以下是一个using static
的例子:
// 使用System.Console类的静态成员
using static System.Console;
class Program
{
static void Main()
{
// 直接调用WriteLine方法,而不需要Console类的前缀
WriteLine("Hello, World!");
}
}
在这个例子中,我们通过using static System.Console;导入了System.Console类的所有静态成员。因此,在Main方法中,我们可以直接使用WriteLine方法,而不需要前面加上Console.。
这种方式可以使代码更加简洁,并且在使用如Math类中的数学函数或Console类中的输入输出函数时特别有用。
-
为类型取别名
在C#中,using
指令可以用来创建类型的别名,这在你想要简化复杂类型名称或解决命名冲突时非常有用。以下是一个使用using
来创建类型别名的例子:
// 为System.Text.StringBuilder创建一个别名Cat
using Cat = System.Text.StringBuilder;
class Program
{
static void Main()
{
// 现在可以使用Cat来代替StringBuilder
Cat cat = new Cat();
cat.Append("Hello, World!");
Console.WriteLine(cat.ToString());
}
}
上面的代码中,我们创建了一个Cat
的别名,它指向了System.Text.StringBuilder
。这样,在Main
方法中我们就可以使用Cat
来代替StringBuilder
,使代码更加简洁。
你还可以为泛型类型创建别名,例如:
// 为List<int>创建一个别名IntList
using IntList = System.Collections.Generic.List<int>;
class Program
{
static void Main()
{
// 使用别名IntList来创建一个整数列表
IntList list = new IntList();
list.Add(1);
list.Add(2);
list.Add(3);
// 输出列表中的元素数量
Console.WriteLine("List count: " + list.Count);
}
}
在这个例子中,IntList
是List<int>
的别名,我们可以使用它来创建和操作整数列表。
-
using scope
在C#中,using
语句通常用于确保即使在发生异常的情况下,也能正确地释放实现了IDisposable
接口的对象。这是通过在using
语句的范围结束时自动调用对象的Dispose
方法来实现的。以下是一个使用using
语句声明变量的例子:
using (var resource = new Resource())
{
// 在这里使用resource
}
// 在这个块的末尾,resource会被自动释放。
在上面的代码中,resource
是一个实现了IDisposable
接口的对象。当控制流离开using
块时,resource
对象的Dispose
方法会被自动调用,从而释放资源。
-
using变量
此外,C# 8.0 引入了using
声明,它允许你在不使用大括号的情况下声明一个需要释放的资源。这样,资源会在它所在的作用域结束时被释放。例如:
static IEnumerable<int> LoadNumbers(string filePath)
{
using StreamReader reader = File.OpenText(filePath);
var numbers = new List<int>();
string line;
while ((line = reader.ReadLine()) != null)
{
if (int.TryParse(line, out int number))
{
numbers.Add(number);
}
}
return numbers;
}
// 在LoadNumbers方法的末尾,reader会被自动释放。
在这个例子中,reader
是在方法作用域内声明的,所以它会在方法结束时被自动释放。这种声明方式使得代码更加简洁,并且可以减少错误的发生。
utf8 字符串字面量
UTF8字符串字面量是C# 11.0版本中引入的一项新特性。这个特性允许开发者直接在代码中写入UTF8编码的字符串,并且这些字符串会在编译时自动转换成UTF-8的字节表示形式。这样做的好处是可以提高性能,因为它避免了运行时的编码转换开销。
使用UTF8字符串字面量非常简单,只需要在字符串字面量后面加上u8
后缀即可。例如:
ReadOnlySpan<byte> utf8String = "hello world"u8;
上面的代码中,"hello world"u8
就是一个UTF8字符串字面量,它会被编译成一个包含hello world
文本UTF-8编码字节的ReadOnlySpan<byte>
类型。这个特性对于需要处理大量文本数据的网络应用和性能敏感的应用来说非常有用。
参考:https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-11.0/utf8-string-literals
文件域的命名空间声明
(File-scoped namespace declaration)
在C# 10中引入了文件域的命名空间声明,这是一种更简洁的命名空间声明方式,它允许整个文件中的所有类型默认都位于同一个命名空间下,而无需使用大括号。这样可以减少代码的缩进,使文件结构更清晰。
以下是一个文件域命名空间声明的例子:
// 文件域命名空间声明
namespace MyNamespace;
// 以下类都位于MyNamespace命名空间中
class MyClassA
{
// 类A的实现
}
class MyClassB
{
// 类B的实现
}
在上面的代码中,MyNamespace是一个文件域的命名空间,它适用于整个文件。这意味着,文件中定义的所有类型(如MyClassA和MyClassB)都会自动包含在MyNamespace命名空间中。