using 的三种使用方式
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 的三种使用方式的更多相关文章
- 通过三个DEMO学会SignalR的三种实现方式
一.理解SignalR ASP .NET SignalR 是一个ASP .NET 下的类库,可以在ASP .NET 的Web项目中实现实时通信(即:客户端(Web页面)和服务器端可以互相实时的通知消息 ...
- Hive metastore三种配置方式
http://blog.csdn.net/reesun/article/details/8556078 Hive的meta数据支持以下三种存储方式,其中两种属于本地存储,一种为远端存储.远端存储比较适 ...
- django 模板语法和三种返回方式
模板 for循环 {% for athlete in athlete_list %} <li>{{ athlete.name }}</li> {% endfor %} if语句 ...
- js的三种继承方式及其优缺点
[转] 第一种,prototype的方式: //父类 function person(){ this.hair = 'black'; this.eye = 'black'; this.skin = ' ...
- spring ioc三种注入方式
spring ioc三种注入方式 IOC ,全称 (Inverse Of Control) ,中文意思为:控制反转 什么是控制反转? 控制反转是一种将组件依赖关系的创建和管理置于程序外部的技术. 由容 ...
- Map三种遍历方式
Map三种遍历方式 package decorator; import java.util.Collection; import java.util.HashMap; import java.util ...
- php 递归函数的三种实现方式
递归函数是我们常用到的一类函数,最基本的特点是函数自身调用自身,但必须在调用自身前有条件判断,否则无限无限调用下去.实现递归函数可以采取什么方式呢?本文列出了三种基本方式.理解其原来需要一定的基础知识 ...
- JSON的三种解析方式
一.什么是JSON? JSON是一种取代XML的数据结构,和xml相比,它更小巧但描述能力却不差,由于它的小巧所以网络传输数据将减少更多流量从而加快速度. JSON就是一串字符串 只不过元素会使用特定 ...
- Qt 2D绘图 渐变填充(三种渐变方式)
在qt中提供了三种渐变方式,分别是线性渐变,圆形渐变和圆锥渐变.如果能熟练应用它们,就能设计出炫目的填充效果. 线性渐变: 1.更改函数如下: void Dialog::paintEvent(QPai ...
- Java多线程的三种实现方式
java多线程的三种实现方式 一.继承Thread类 二.实现Runnable接口 三.使用ExecutorService, Callable, Future 无论是通过继承Thread类还是实现Ru ...
随机推荐
- Ubuntu 14.04服务器配置 (1) 安装和配置
http://jingyan.baidu.com/article/9c69d48fb9fd7b13c8024e6b.html ssh是一种安全协议,主要用于给远程登录会话数据进行加密,保证数据传输的安 ...
- python Polygon模块安装
pip install Polygon这样会安装不了 只能使用pip install Polygon2 或者 pip install Polygon3,也就是必须带版本号
- shell编程之测试和判断
一.测试 程序运行中经常需要根据实际情况来运行特定的命令或代码段.比如判断某个文件或目录是否存在,如果文件或目录不存在,可能首先创建文件或目录.举例说,要判断文件/var/log/mlocate文件是 ...
- dijkstra P4779 【模板】单源最短路径(标准版) 洛谷luogu
题目背景 2018 年 7 月 19 日,某位同学在 NOI Day 1 T1 归程 一题里非常熟练地使用了一个广为人知的算法求最短路. 然后呢? 100→60 Ag→Cu 最终,他因此没能与理想的大 ...
- PAT A1097 Deduplication on a Linked List (25 分)——链表
Given a singly linked list L with integer keys, you are supposed to remove the nodes with duplicated ...
- java 迭代器遍历List Set Map
Iterator接口: 所有实现了Collection接口的容器类都有一个iterator方法用以返回一个实现Iterator接口的对象 Iterator对象称作为迭代器,用以方便的对容器内元素的遍历 ...
- 在lua中创建字段安全的对象
lua萌新,刚刚学习和使用不到一个月.有不对的地方,还望各路大神不吝赐教. lua中可以用table来模拟对象,但table是可以任意增加键值的.在对象模拟中,暂且也叫它为字段(field)吧.如果在 ...
- excel保存为制表符分隔的文本文件 js无法完整读取
excel保存为制表符分隔的文本文件 js无法完整读取 excel另存为文本有两个选项,一个是制表符分隔的文本文件,一个是unicode文本.生成的文件Unicode更大一些.但是这里需要注意的是[制 ...
- LOJ2803 CCC2018 平衡树 数论分块、记忆化搜索
传送门 题意差评,其实就是一个递推式:\(f_1 = 1 , f_i = \sum\limits_{j=2}^i f_{\lfloor \frac{i}{j} \rfloor}\),然后求\(f_N\ ...
- 截取字符串中最后一个中文词语(MS SQL)
有朋友需求一个问题,就是处理一张表中某一字段,从这个字段中去截取内容中最后一个中文词语. ID SourceText Result 1 张达:U:1杨英苹:U:1,周忱:U:1,;苗桥:U:1,章玮: ...