using 关键字有两个主要用途:

  • 作为指令:用于为命名空间创建别名或导入在其他命名空间中定义的类型。

  • 作为语句:用于定义一个范围,在此范围的末尾将释放对象。

此外,使用 using 静态指令可定义一种类型,在未指定类型名称的情况下即可访问该类型的静态成员

using 指令有三种用途:

  • 允许在命名空间中使用类型,这样无需在该命名空间中限定某个类型的使用:

    using System.Text;
  • 允许访问类型的静态成员,而无需限定使用类型名称进行访问。

    using static System.Math;  
  • 为命名空间或类型创建别名。 这称为 using 别名指令

    using Project = PC.MyCompany.Project;

using 关键字还用于创建 using 语句,此类语句有助于确保正确处理 IDisposable 对象(如文件和字体)。

Using Static 类型

你可以访问类型的静态成员,而无需限定使用类型名称进行访问:

using static System.Console;
using static System.Math;
class Program
{
static void Main()
{
WriteLine(Sqrt(3*3 + 4*4));
}
}

备注

using 指令的范围限于显示它的文件。

创建 using 别名,以便更易于将标识符限定为命名空间或类型。 using 别名指令的右侧必须始终是一个完全限定类型,而与前面的 using 指令无关。

创建 using 指令,以便在命名空间中使用类型而不必指定命名空间。 using 指令不为你提供对嵌套在指定命名空间中的任何命名空间的访问权限。

命名空间分为两类:用户定义的命名空间和系统定义的命名空间。 用户定义的命名空间是在代码中定义的命名空间。 有关系统定义的命名空间的列表,请参阅 .NET Framework 类库

示例 1

下面的示例显示如何为命名空间定义和使用 using 别名:

namespace PC
{
// Define an alias for the nested namespace.
using Project = PC.MyCompany.Project;
class A
{
void M()
{
// Use the alias
Project.MyClass mc = new Project.MyClass();
}
}
namespace MyCompany
{
namespace Project
{
public class MyClass { }
}
}
}

using 别名指令的右侧不能有开放式泛型类型。 例如,不能为 List<T> 创建 using 别名,但可以为 List<int> 创建。

示例 2

下面的示例显示如何为类定义 using 指令和 using 别名:

using System;

// Using alias directive for a class.
using AliasToMyClass = NameSpace1.MyClass; // Using alias directive for a generic class.
using UsingAlias = NameSpace2.MyClass<int>; namespace NameSpace1
{
public class MyClass
{
public override string ToString()
{
return "You are in NameSpace1.MyClass.";
}
} } namespace NameSpace2
{
class MyClass<T>
{
public override string ToString()
{
return "You are in NameSpace2.MyClass.";
}
}
} namespace NameSpace3
{
// Using directive:
using NameSpace1;
// Using directive:
using NameSpace2; class MainClass
{
static void Main()
{
AliasToMyClass instance1 = new AliasToMyClass();
Console.WriteLine(instance1); UsingAlias instance2 = new UsingAlias();
Console.WriteLine(instance2); }
}
}
// Output:
// You are in NameSpace1.MyClass.
// You are in NameSpace2.MyClass.

using static 指令

指定无需指定类型名称即可访问其静态成员的类型。 语法为:

using static <fully-qualified-type-name>

其中,fully-qualified-type-name 是无需指定类型名称即可访问其静态成员的类型的名称。 如果不提供完全限定的类型名称(完整的命名空间名称以及类型名称),则 C# 将生成编译器错误 CS0246:“找不到‘’的类型或命名空间名称。”

using static 指令适用于任何具有静态成员的类型,即使该类型还具有实例成员。 但是,只能通过类型实例来调用实例成员。

using static 指令是在 C# 6 中引入的。

备注

通常,调用某个静态成员时,即会提供类型名称以及成员名称。 重复输入相同的类型名称来调用该类型的成员将生成详细的晦涩代码。 例如,Circle 类的以下定义引用Math 类的成员数。

using System;

public class Circle
{
public Circle(double radius)
{
Radius = radius;
} public double Radius { get; set; } public double Diameter
{
get { return 2 * Radius; }
} public double Circumference
{
get { return 2 * Radius * Math.PI; }
} public double Area
{
get { return Math.PI * Math.Pow(Radius, 2); }
}
}

通过消除每次引用成员时,显式引用 Math 类的需求,using static 指令将生成更简洁的代码:

using System;
using static System.Math; public class Circle
{
public Circle(double radius)
{
Radius = radius;
} public double Radius { get; set; } public double Diameter
{
get { return 2 * Radius; }
} public double Circumference
{
get { return 2 * Radius * PI; }
} public double Area
{
get { return PI * Pow(Radius, 2); }
}
}

using static 仅导入可访问的静态成员和指定类型中声明的嵌套类型。 不导入继承的成员。 可以从任何带 using static 指令的已命名类型导入,包括 Visual Basic 模块。 如果 F# 顶级函数在元数据中显示为一个已命名类型(其名称是有效的 C# 标识符)的静态成员,则可以导入该 F# 函数。

using static 使指定类型中声明的扩展方法可用于扩展方法查找。 但是,扩展方法的名称不导入到代码中非限定引用的作用域中。

同一编译单元或命名空间中通过不同 using static 命令从不同类型导入的具有相同名称的方法组成一个方法组。 这些方法组内的重载解决方法遵循一般 C# 规则。

示例

以下示例使用 using static 指令来提供 @System.Console、@System.Math 和 String类的静态成员,而无需指定其类型名称。

using System;
using static System.Console;
using static System.Math;
using static System.String; class Program
{
static void Main()
{
Write("Enter a circle's radius: ");
var input = ReadLine();
if (!IsNullOrEmpty(input) && double.TryParse(input, out var radius)) {
var c = new Circle(radius); string s = "\nInformation about the circle:\n";
s = s + Format(" Radius: {0:N2}\n", c.Radius);
s = s + Format(" Diameter: {0:N2}\n", c.Diameter);
s = s + Format(" Circumference: {0:N2}\n", c.Circumference);
s = s + Format(" Area: {0:N2}\n", c.Area);
WriteLine(s);
}
else {
WriteLine("Invalid input...");
}
}
} public class Circle
{
public Circle(double radius)
{
Radius = radius;
} public double Radius { get; set; } public double Diameter
{
get { return 2 * Radius; }
} public double Circumference
{
get { return 2 * Radius * PI; }
} public double Area
{
get { return PI * Pow(Radius, 2); }
}
}
// The example displays the following output:
// Enter a circle's radius: 12.45
//
// Information about the circle:
// Radius: 12.45
// Diameter: 24.90
// Circumference: 78.23
// Area: 486.95

在此示例中,using static 指令也已经应用于 Double 类型。 这使得在未指定类型名称情况下调用 TryParse(String, Double) 方法成为可能。 但是,如此创建的代码可读性较差,因为这样有必要检查 using static 语句,以确定所调用的数值类型的 TryParse 方法。

using 语句

提供可确保正确使用 IDisposable 对象的方便语法。

示例

下面的示例演示如何使用 using 语句。

using (Font font1 = new Font("Arial", 10.0f))
{
byte charset = font1.GdiCharSet;
}

备注

File 和 Font 是访问非托管资源(本例中为文件句柄和设备上下文)的托管类型的示例。 有许多其他类别的非托管资源和封装这些资源的类库类型。 所有此类类型都必须实现 IDisposable 接口。

通常,使用 IDisposable 对象时,应在 using 语句中声明和实例化此对象。 using语句按照正确的方式调用对象上的 Dispose 方法,并(在按照前面所示方式使用它时)会导致在调用 Dispose 时对象自身处于范围之外。 在 using 块中,对象是只读的并且无法进行修改或重新分配。

using 语句确保调用 Dispose,即使在调用对象上的方法时出现异常也是如此。 通过将对象放入 try 块中,然后调用 finally 块中的 Dispose,可以实现相同的结果;实际上,这就是编译器转换 using 语句的方式。 前面的代码示例在编译时将扩展到以下代码(请注意,使用额外的大括号为对象创建有限范围):

{
Font font1 = new Font("Arial", 10.0f);
try
{
byte charset = font1.GdiCharSet;
}
finally
{
if (font1 != null)
((IDisposable)font1).Dispose();
}
}

可在 using 语句中声明一个类型的多个实例,如下面的示例中所示。

using (Font font3 = new Font("Arial", 10.0f),
font4 = new Font("Arial", 10.0f))
{
// Use font3 and font4.
}

可以实例化资源对象,然后将变量传递到 using 语句,但这不是最佳做法。 在这种情况下,该对象将在控制权离开 using 块之后保持在范围内,即使它可能将不再具有对其非托管资源的访问权限。 换句话说,再也无法完全初始化该对象。 如果尝试在 using 块外部使用该对象,则可能导致引发异常。 因此,通常最好在 using 语句中实例化该对象并将其范围限制在 using 块中。

Font font2 = new Font("Arial", 10.0f);
using (font2) // not recommended
{
// use font2
}
// font2 is still in scope
// but the method call throws an exception
float f = font2.GetHeight();
参考文献:
https://docs.microsoft.com/zh-cn/dotnet/csharp/language-reference/keywords/using
     
https://docs.microsoft.com/zh-cn/dotnet/csharp/index

using 的三种使用方式的更多相关文章

  1. 通过三个DEMO学会SignalR的三种实现方式

    一.理解SignalR ASP .NET SignalR 是一个ASP .NET 下的类库,可以在ASP .NET 的Web项目中实现实时通信(即:客户端(Web页面)和服务器端可以互相实时的通知消息 ...

  2. Hive metastore三种配置方式

    http://blog.csdn.net/reesun/article/details/8556078 Hive的meta数据支持以下三种存储方式,其中两种属于本地存储,一种为远端存储.远端存储比较适 ...

  3. django 模板语法和三种返回方式

    模板 for循环 {% for athlete in athlete_list %} <li>{{ athlete.name }}</li> {% endfor %} if语句 ...

  4. js的三种继承方式及其优缺点

    [转] 第一种,prototype的方式: //父类 function person(){ this.hair = 'black'; this.eye = 'black'; this.skin = ' ...

  5. spring ioc三种注入方式

    spring ioc三种注入方式 IOC ,全称 (Inverse Of Control) ,中文意思为:控制反转 什么是控制反转? 控制反转是一种将组件依赖关系的创建和管理置于程序外部的技术. 由容 ...

  6. Map三种遍历方式

    Map三种遍历方式 package decorator; import java.util.Collection; import java.util.HashMap; import java.util ...

  7. php 递归函数的三种实现方式

    递归函数是我们常用到的一类函数,最基本的特点是函数自身调用自身,但必须在调用自身前有条件判断,否则无限无限调用下去.实现递归函数可以采取什么方式呢?本文列出了三种基本方式.理解其原来需要一定的基础知识 ...

  8. JSON的三种解析方式

    一.什么是JSON? JSON是一种取代XML的数据结构,和xml相比,它更小巧但描述能力却不差,由于它的小巧所以网络传输数据将减少更多流量从而加快速度. JSON就是一串字符串 只不过元素会使用特定 ...

  9. Qt 2D绘图 渐变填充(三种渐变方式)

    在qt中提供了三种渐变方式,分别是线性渐变,圆形渐变和圆锥渐变.如果能熟练应用它们,就能设计出炫目的填充效果. 线性渐变: 1.更改函数如下: void Dialog::paintEvent(QPai ...

  10. Java多线程的三种实现方式

    java多线程的三种实现方式 一.继承Thread类 二.实现Runnable接口 三.使用ExecutorService, Callable, Future 无论是通过继承Thread类还是实现Ru ...

随机推荐

  1. Domain Adaptation (1)选题讲解

    1 所选论文 论文题目: <Unsupervised Domain Adaptation with Residual Transfer Networks> 论文信息: NIPS2016, ...

  2. ucml JS调用其它页面上的服务端方法

    var params = { _bpoName: "BPO_KH_ED" + "Service", //BPO的名字(拥有那个服务端函数的BPO) _metho ...

  3. python3 day03 大纲

    一. 上次课内容回顾 1. 格式化输出 %d 占位数字 %s 占位字符串 %f 占位小数 "jfklasjkfj%s %d %f" % (值1, 值2, 值3) "{}爱 ...

  4. java 迭代器遍历List Set Map

    Iterator接口: 所有实现了Collection接口的容器类都有一个iterator方法用以返回一个实现Iterator接口的对象 Iterator对象称作为迭代器,用以方便的对容器内元素的遍历 ...

  5. Linux命令——cat/less/more的区别

    cat命令:用于显示整个文件的内容,单独使用没有翻页功能,经常和 more 命令搭配使用,cat 命令还可以将数个文件合并成一个文件. more命令:让画面在显示满一页时暂停,此时可按空格健继续显示下 ...

  6. python条件、循环语句

    既然讲到语句,那先说明一下语句块.语句块不是一种语句,是一组语句.在条件为真时执行或者多次的一组语句.主要注意其格式,用冒号来标识语句块的开始,块中每行缩进相同的量,一般4个空格(tab字符位置为8个 ...

  7. java中使用阻塞队列实现生产这与消费这之间的关系

    需求如下: 有一个生产者和一个消费者,生产者不断的生产产品,消费这不断的消费产品.产品总数为N. 1.生产顺序按队列的方式,先进先出. 2.生产者和消费这可以同时进行. 3.当生产者生产了N个产品后不 ...

  8. Tensorflow-hub[例子解析2]

    接Tensorflow-hub[例子解析1]. 3 基于文本词向量的例子 3.1 创建Module 可以从Tensorflow-hub[例子解析1].中看出,hub相对之前减少了更多的工作量. 首先, ...

  9. Luogu4137 Rmq problem/mex 主席树

    传送门 用主席树水莫队题…… 我们对于前缀和建立主席树,对于主席树中的每一个叶子节点表示它对应的数字最后出现的位置的编号,非叶子节点求左右节点的最小值,那么对于每一次询问$l,r$就是在第$r$棵主席 ...

  10. CF939D Love Rescue 并查集

    传送门 题意:给出两个由小写字母构成的长度相等的字符串$S$与$T$,给出变换$c1\,c2$表示将两个字符串中所有$c1$字符变为$c2$,求将$S$和$T$通过这种变换变为相等字符串的最少变换次数 ...