Skip to content

Commit

Permalink
Clarify using directive examples (#43580)
Browse files Browse the repository at this point in the history
  • Loading branch information
BillWagner authored Nov 15, 2024
1 parent a829f87 commit b374b8b
Show file tree
Hide file tree
Showing 9 changed files with 63 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ Default projects should compile.

If you relied on the implicit global `using` directive, you can:

- Add a [global `using` directive](../../../../csharp/language-reference/keywords/using-directive.md#global-modifier) to one of your source files.
- Add a [global `using` directive](../../../../csharp/language-reference/keywords/using-directive.md#the-global-modifier) to one of your source files.
- Add a `using` directive to each source code file that uses APIs from System.Net.Http.

## Affected APIs
Expand Down
4 changes: 2 additions & 2 deletions docs/core/project-sdk/msbuild-props.md
Original file line number Diff line number Diff line change
Expand Up @@ -1751,7 +1751,7 @@ For more information, see [Trimming options](../deploying/trimming/trimming-opti

### Using

The `Using` item lets you [globally include a namespace](../../csharp/language-reference/keywords/using-directive.md#global-modifier) across your C# project, such that you don't have to add a `using` directive for the namespace at the top of your source files. This item is similar to the `Import` item that can be used for the same purpose in Visual Basic projects. This property is available starting in .NET 6.
The `Using` item lets you [globally include a namespace](../../csharp/language-reference/keywords/using-directive.md#the-global-modifier) across your C# project, such that you don't have to add a `using` directive for the namespace at the top of your source files. This item is similar to the `Import` item that can be used for the same purpose in Visual Basic projects. This property is available starting in .NET 6.

```xml
<ItemGroup>
Expand All @@ -1772,7 +1772,7 @@ For example:
- `<Using Include="Microsoft.AspNetCore.Http.Results" Alias="Results" />` emits `global using Results = global::Microsoft.AspNetCore.Http.Results;`
- `<Using Include="Microsoft.AspNetCore.Http.Results" Static="True" />` emits `global using static global::Microsoft.AspNetCore.Http.Results;`

For more information, see [aliased `using` directives](../../csharp/language-reference/keywords/using-directive.md#using-alias) and [`using static <type>` directives](../../csharp/language-reference/keywords/using-directive.md#static-modifier).
For more information, see [aliased `using` directives](../../csharp/language-reference/keywords/using-directive.md#the-using-alias) and [`using static <type>` directives](../../csharp/language-reference/keywords/using-directive.md#the-static-modifier).

## Item metadata

Expand Down
2 changes: 1 addition & 1 deletion docs/core/project-sdk/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ If you explicitly define any of these items in your project file, you're likely

## Implicit using directives

Starting in .NET 6, implicit [`global using` directives](../../csharp/language-reference/keywords/using-directive.md#global-modifier) are added to new C# projects. This means that you can use types defined in these namespaces without having to specify their fully qualified name or manually add a `using` directive. The *implicit* aspect refers to the fact that the `global using` directives are added to a generated file in the project's *obj* directory.
Starting in .NET 6, implicit [`global using` directives](../../csharp/language-reference/keywords/using-directive.md#the-global-modifier) are added to new C# projects. This means that you can use types defined in these namespaces without having to specify their fully qualified name or manually add a `using` directive. The *implicit* aspect refers to the fact that the `global using` directives are added to a generated file in the project's *obj* directory.

Implicit `global using` directives are added for projects that use one of the following SDKs:

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ At compile time, the compiler replaces non-default field names with the correspo
> [!TIP]
> Enable .NET code style rule [IDE0037](../../../fundamentals/code-analysis/style-rules/ide0037.md) to set a preference on inferred or explicit tuple field names.
Beginning with C# 12, you can specify an alias for a tuple type with a [`using` directive](../keywords/using-directive.md#using-alias). The following example adds a `global using` alias for a tuple type with two integer values for an allowed `Min` and `Max` value:
Beginning with C# 12, you can specify an alias for a tuple type with a [`using` directive](../keywords/using-directive.md#the-using-alias). The following example adds a `global using` alias for a tuple type with two integer values for an allowed `Min` and `Max` value:

:::code language="csharp" source="snippets/shared/ValueTuples.cs" id="AliasTupleType":::

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ In addition, if you define an alias named `global`, the compiler issues **CS0440

## Alias name conflicts

You can declare an [alias](../keywords/using-directive.md#using-alias) to a namespace or a type with a `using` directive:
You can declare an [alias](../keywords/using-directive.md#the-using-alias) to a namespace or a type with a `using` directive:

:::code language="csharp" source="./snippets/UsingDirectives/Program.cs" id="UsingAlias":::

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@

// <UsingAliasQualifier>
using S = System.Net.Sockets;

class A
{
public static int x;
}

class C
{
public void F(int A, object S)
{
// Use global::A.x instead of A.x
global::A.x += A;

// Using ::, S must resolve to a namespace alias:
S::Socket s = S as S::Socket;

// In this form, if S were a class, it would be a compile-time error:
S.Socket s1 = S as S.Socket;
}
}
// </UsingAliasQualifier>
51 changes: 31 additions & 20 deletions docs/csharp/language-reference/keywords/using-directive.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
---
description: "using directive - C# Reference"
title: "using directive"
ms.date: 08/19/2021
description: "The `using` directive imports types from a namespace, or creates an alias for a given type. Using directives enable you to use simple names for types instead of the fully qualified type name."
title: "The using directive: Import types from a namespace"
ms.date: 11/14/2024
f1_keywords:
- "using_CSharpKeyword"
helpviewer_keywords:
- "using directive [C#]"
ms.assetid: b42b8e61-5e7e-439c-bb71-370094b44ae8
---
# using directive
# The `using` directive

The `using` directive allows you to use types defined in a namespace without specifying the fully qualified namespace of that type. In its basic form, the `using` directive imports all the types from a single namespace, as shown in the following example:

Expand All @@ -21,7 +20,7 @@ You can apply two modifiers to a `using` directive:
- The `global` modifier has the same effect as adding the same `using` directive to every source file in your project. This modifier was introduced in C# 10.
- The `static` modifier imports the `static` members and nested types from a single type rather than importing all the types in a namespace.

You can combine both modifiers to import the static members from a type in all source files in your project.
You can combine both modifiers to import the static members from a type to all source files in your project.

You can also create an alias for a namespace or a type with a *using alias directive*.

Expand All @@ -36,43 +35,47 @@ You can use the `global` modifier on a *using alias directive*.
The scope of a `using` directive without the `global` modifier is the file in which it appears.

The `using` directive can appear:
The `global using` directive must appear before all namespace and type declarations. All global using directives must appear in a source file before any nonglobal `using` directives.

Other `using` directives can appear:

- At the beginning of a source code file, before any namespace or type declarations.
- In any namespace, but before any namespaces or types declared in that namespace, unless the `global` modifier is used, in which case the directive must appear before all namespace and type declarations.
- In any blocked-scoped namespace, but before any namespaces or types declared in that namespace.

Otherwise, compiler error [CS1529](../compiler-messages/using-directive-errors.md) is generated.
Otherwise, a compiler error is generated.

Create a `using` directive to use the types in a namespace without having to specify the namespace. A `using` directive doesn't give you access to any namespaces that are nested in the namespace you specify. Namespaces come in two categories: user-defined and system-defined. User-defined namespaces are namespaces defined in your code. For a list of the system-defined namespaces, see [.NET API Browser](../../../../api/index.md).

## global modifier
## The `global` modifier

Adding the `global` modifier to a `using` directive means that using is applied to all files in the compilation (typically a project). The `global using` directive was added in C# 10. Its syntax is:

```csharp
global using <fully-qualified-namespace>;
```

where *fully-qualified-namespace* is the fully qualified name of the namespace whose types can be referenced without specifying the namespace.
Where *fully-qualified-namespace* is the fully qualified name of the namespace whose types can be referenced without specifying the namespace.

A *global using* directive can appear at the beginning of any source code file. All `global using` directives in a single file must appear before:

- All `using` directives without the `global` modifier.
- All namespace and type declarations in the file.

You may add `global using` directives to any source file. Typically, you'll want to keep them in a single location. The order of `global using` directives doesn't matter, either in a single file, or between files.
You can add `global using` directives to any source file. Typically, you want to keep them in a single location. The order of `global using` directives doesn't matter, either in a single file, or between files.

The `global` modifier may be combined with the `static` modifier. The `global` modifier may be applied to a *using alias directive*. In both cases, the directive's scope is all files in the current compilation. The following example enables using all the methods declared in the <xref:System.Math?displayProperty=fullName> in all files in your project:
The `global` modifier can be combined with the `static` modifier. The `global` modifier can be applied to a *using alias directive*. In both cases, the directive's scope is all files in the current compilation. The following example enables using all the methods declared in the <xref:System.Math?displayProperty=fullName> in all files in your project:

```csharp
global using static System.Math;
```

You can also globally include a namespace by adding a `<Using>` item to your project file, for example, `<Using Include="My.Awesome.Namespace" />`. For more information, see [`<Using>` item](../../../core/project-sdk/msbuild-props.md#using).

Analyzers issue diagnostics if you duplicate `global` using directives in different locations. These same analyzers also inform you if you add a `using` directive for a namespace or type that a `global` using directive already references. You might find it easier to manage your `global` usings by keeping them together in one file in the project.

[!INCLUDE [csharp10-templates](../../../../includes/csharp10-templates.md)]

## static modifier
## The `static` modifier

The `using static` directive names a type whose static members and nested types you can access without specifying a type name. Its syntax is:

Expand Down Expand Up @@ -106,19 +109,19 @@ By eliminating the need to explicitly reference the <xref:System.Math> class eac

:::code language="csharp" source="./snippets/using-static2.cs":::

`using static` imports only accessible static members and nested types declared in the specified type. Inherited members aren't imported. You can import from any named type with a `using static` directive, including Visual Basic modules. 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` imports only accessible static members and nested types declared in the specified type. Inherited members aren't imported. You can import from any named type with a `using static` directive, including Visual Basic modules. 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` makes extension methods declared in the specified type available for extension method lookup. However, the names of the extension methods aren't imported into scope for unqualified reference in code.
`using static` makes extension methods declared in the specified type available for extension method lookup. However, the names of the extension methods aren't imported into scope for unqualified reference in code.

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. Overload resolution within these method groups follows normal C# rules.
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. Overload resolution within these method groups follows normal C# rules.

The following example uses the `using static` directive to make the static members of the <xref:System.Console>, <xref:System.Math>, and <xref:System.String> classes available without having to specify their type name.

:::code language="csharp" source="./snippets/using-static3.cs" id="Snippet1":::

In the example, the `using static` directive could also have been applied to the <xref:System.Double> type. Adding that directive would make it possible to call the <xref:System.Double.TryParse(System.String,System.Double@)> method without specifying a type name. However, using `TryParse` without a type name creates less readable code, since it becomes necessary to check the `using static` directives to determine which numeric type's `TryParse` method is called.
In the example, the `using static` directive could also be applied to the <xref:System.Double> type. Adding that directive would make it possible to call the <xref:System.Double.TryParse(System.String,System.Double@)> method without specifying a type name. However, using `TryParse` without a type name creates less readable code, since it becomes necessary to check the `using static` directives to determine which numeric type's `TryParse` method is called.

`using static` also applies to `enum` types. By adding `using static` with the enum, the type is no longer required to use the enum members.
`using static` also applies to `enum` types. By adding `using static` with the enum, the type is no longer required to use the enum members.

```csharp
using static Color;
Expand All @@ -139,7 +142,7 @@ class Program
}
```

## using alias
## The `using` alias

Create a `using` alias directive to make it easier to qualify an identifier to a namespace or type. In any `using` directive, the fully qualified namespace or type must be used regardless of the `using` directives that come before it. No `using` alias can be used in the declaration of a `using` directive. For example, the following example generates a compiler error:

Expand All @@ -160,6 +163,14 @@ The following example shows how to define a `using` directive and a `using` alia

Beginning with C# 12, you can create aliases for types that were previously restricted, including [tuple types](../builtin-types/value-tuples.md#tuple-field-names), pointer types, and other unsafe types. For more information on the updated rules, see the [feature spec](~/_csharplang/proposals/csharp-12.0/using-alias-types.md).

## Qualified alias member

The namespace alias qualifier, `::` provides explicit access to the global namespace or other using aliases potentially hidden by other entities.

The `global::` ensures that the namespace lookup for the namespace following the `::` token is relative to the global namespace. Otherwise, the token must resolve to a using alias, and the token following the `::` must resolve to a type in that aliased namespace. The following example shows both forms:

:::code language="csharp" source="./snippets/UsingAliasQualifier.cs" id="UsingAliasQualifier":::

## C# language specification

For more information, see [Using directives](~/_csharpstandard/standard/namespaces.md#145-using-directives) in the [C# Language Specification](~/_csharpstandard/standard/README.md). The language specification is the definitive source for C# syntax and usage.
Expand Down
2 changes: 1 addition & 1 deletion docs/csharp/linq/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ The following example shows a complete query operation. The complete operation i

:::code language="csharp" source="./snippets/linq-index/Index.cs" id="intro":::

You might need to add a [`using`](../language-reference/keywords/using-directive.md) directive, `using System.Linq;`, for the preceding example to compile. The most recent versions of .NET make use of [implicit usings](../../core/project-sdk/overview.md#implicit-using-directives) to add this directive as a [global using](../language-reference/keywords/using-directive.md#global-modifier). Older versions require you to add it in your source.
You might need to add a [`using`](../language-reference/keywords/using-directive.md) directive, `using System.Linq;`, for the preceding example to compile. The most recent versions of .NET make use of [implicit usings](../../core/project-sdk/overview.md#implicit-using-directives) to add this directive as a [global using](../language-reference/keywords/using-directive.md#the-global-modifier). Older versions require you to add it in your source.

## Query expression overview

Expand Down
2 changes: 1 addition & 1 deletion docs/csharp/tour-of-csharp/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ The preceding example shows one form of a "Hello, World" program, using [top-lev

:::code language="csharp" interactive="try-dotnet" source="./snippets/shared/HelloWorld.cs":::

This version shows the building blocks you use in your programs. The "Hello, World" program starts with a `using` directive that references the `System` namespace. Namespaces provide a hierarchical means of organizing C# programs and libraries. Namespaces contain types and other namespaces—for example, the `System` namespace contains many types, such as the `Console` class referenced in the program, and many other namespaces, such as `IO` and `Collections`. A `using` directive that references a given namespace enables unqualified use of the types that are members of that namespace. Because of the `using` directive, the program can use `Console.WriteLine` as shorthand for `System.Console.WriteLine`. In the earlier example, that namespace was [implicitly](../language-reference/keywords/using-directive.md#global-modifier) included.
This version shows the building blocks you use in your programs. The "Hello, World" program starts with a `using` directive that references the `System` namespace. Namespaces provide a hierarchical means of organizing C# programs and libraries. Namespaces contain types and other namespaces—for example, the `System` namespace contains many types, such as the `Console` class referenced in the program, and many other namespaces, such as `IO` and `Collections`. A `using` directive that references a given namespace enables unqualified use of the types that are members of that namespace. Because of the `using` directive, the program can use `Console.WriteLine` as shorthand for `System.Console.WriteLine`. In the earlier example, that namespace was [implicitly](../language-reference/keywords/using-directive.md#the-global-modifier) included.

The `Hello` class declared by the "Hello, World" program has a single member, the method named `Main`. The `Main` method is declared with the `static` modifier. While instance methods can reference a particular enclosing object instance using the keyword `this`, static methods operate without reference to a particular object. By convention, when there are no top-level statements a static method named `Main` serves as the [entry point](../fundamentals/program-structure/main-command-line.md) of a C# program.

Expand Down

0 comments on commit b374b8b

Please sign in to comment.