using 静态指令(C# 参考)using static directive (C# Reference)

using static 指令指定一种类型,无需指定类型名称即可访问其静态成员和嵌套类型。The using static directive designates a type whose static members and nested types you can access without specifying a type name. 语法为:Its syntax is:

using static <fully-qualified-type-name>;

其中,fully-qualified-type-name 是无需指定类型名称即可访问其静态成员和嵌套类型的类型名称 。where fully-qualified-type-name is the name of the type whose static members and nested types can be referenced without specifying a type name. 如果你不提供完全限定的类型名称(完整的命名空间名称以及类型名称),C# 便会生成编译器错误 CS0246:“找不到类型名称或命名空间名称 ’type/namespace’ (是否缺少 using 指令或程序集引用?)”。If you do not provide a fully qualified type name (the full namespace name along with the type name), C# generates compiler error CS0246: "The type or namespace name 'type/namespace' could not be found (are you missing a using directive or an assembly reference?)".

using static 指令适用于任何具有静态成员(或嵌套类型)的类型,即使该类型还具有实例成员。The using static directive applies to any type that has static members (or nested types), even if it also has instance members. 但是,只能通过类型实例来调用实例成员。However, instance members can only be invoked through the type instance.

using static 指令是在 C# 6 中引入的。The using static directive was introduced in C# 6.

备注Remarks

通常,调用某个静态成员时,即会提供类型名称以及成员名称。Ordinarily, when you call a static member, you provide the type name along with the member name. 重复输入相同的类型名称来调用该类型的成员将生成详细的晦涩代码。Repeatedly entering the same type name to invoke members of the type can result in verbose, obscure code. 例如,Circle 类的以下定义引用 Math 类的成员数。For example, the following definition of a Circle class references a number of members of the Math class.

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 指令将生成更简洁的代码:By eliminating the need to explicitly reference the Math class each time a member is referenced, the using static directive produces much cleaner code:

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 imports only accessible static members and nested types declared in the specified type. 不导入继承的成员。Inherited members are not imported. 可以从任何带 using static 指令的已命名类型导入,包括 Visual Basic 模块。You can import from any named type with a using static directive, including Visual Basic modules. 如果 F# 顶级函数在元数据中显示为一个已命名类型(其名称是有效的 C# 标识符)的静态成员,则可以导入该 F# 函数。If F# top-level functions appear in metadata as static members of a named type whose name is a valid C# identifier, then the F# functions can be imported.

using static 使指定类型中声明的扩展方法可用于扩展方法查找。using static makes extension methods declared in the specified type available for extension method lookup. 但是,扩展方法的名称不导入到代码中非限定引用的作用域中。However, the names of the extension methods are not imported into scope for unqualified reference in code.

同一编译单元或命名空间中通过不同 using static 命令从不同类型导入的具有相同名称的方法组成一个方法组。Methods with the same name imported from different types by different using static directives in the same compilation unit or namespace form a method group. 这些方法组内的重载解决方法遵循一般 C# 规则。Overload resolution within these method groups follows normal C# rules.

示例Example

以下示例使用 using static 指令来提供 ConsoleMathString 类的静态成员,而无需指定其类型名称。The following example uses the using static directive to make the static members of the Console, Math, and String classes available without having to specify their type name.

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 类型。In the example, the using static directive could also have been applied to the Double type. 这使得在未指定类型名称情况下调用 TryParse(String, Double) 方法成为可能。This would have made it possible to call the TryParse(String, Double) method without specifying a type name. 但是,如此创建的代码可读性较差,因为这样有必要检查 using static 语句,以确定所调用的数值类型的 TryParse 方法。However, this creates less readable code, since it becomes necessary to check the using static statements to determine which numeric type's TryParse method is called.

请参阅See also