Home > Articles

Parameters and Methods

This chapter is from the book

This chapter is from the book

Using Directives

Fully qualified namespace names can become quite long and unwieldy. It is possible, however, to import all the types from one or more namespaces so that they can be used without full qualification.

Using Directive Overview

Rather than a declarative that applies to the entire project, C# includes a using directive that applies only to the current file. For example, Listing 5.8 (with Output 5.2) doesn’t prefix RegEx with System.Text.RegularExpressions. The namespace may be omitted because of the using System.Text.RegularExpressions directive that appears at the top of the listing.

Listing 5.8: Using Directive Example

// The using directive imports all types from the 
// specified namespace into the entire file
using System.Text.RegularExpressions;
 
public class Program
{
    public static void Main()
    {
        const string firstName = "FirstName";
        const string initial = "Initial";
        const string lastName = "LastName";
 
        // Explaining regular expressions is beyond the
        // scope of this book.
        // See https://www.regular-expressions.info/ for
        // more information.
        const string pattern = $"""
            (?<{firstName}>\w+)\s+((?<{
            initial}>\w)\.\s+)?(?<{
            lastName}>\w+)\s*
            """;
 
        Console.WriteLine(
            "Enter your full name (e.g. Inigo T. Montoya): ");
        string name = Console.ReadLine()!;
 
        // No need to qualify RegEx type with                                                
        // System.Text.RegularExpressions because                                            
        // of the using directive above                                                      
        Match match = Regex.Match(name, pattern);                                            
 
        if (match.Success)
        {
            Console.WriteLine(
                $"{firstName}: {match.Groups[firstName]}");
            Console.WriteLine(
                $"{initial}: {match.Groups[initial]}");
            Console.WriteLine(
                $"{lastName}: {match.Groups[lastName]}");
        }
    }
}

Output 5.2

Hello, my name is Inigo Montoya

A using directive such as using System.Text does not enable you to omit System.Text from a type declared within a nested namespace such as System .Text.RegularExpressions. For example, if your code accessed the RegEx type from the System.Text.RegularExpressions namespace, you would have to either include an additional using System.Text .RegularExpressions directive or fully qualify the type as System.Text .RegularExpressions.RegEx, not just RegularExpressions.RegEx. In short, a using directive does not import types from any nested namespaces. Nested namespaces, which are identified by the period in the namespace, always need to be imported explicitly.

Frequent use of types within a particular namespace implies that the addition of a using directive for that namespace is a good idea, instead of fully qualifying all types within the namespace. Accordingly, almost all C# files include the using System directive at the top. Throughout the remainder of this book, code listings often omit the using System directive from the manuscript. Other namespace directives are generally included explicitly, however.

One interesting effect of the using System directive is that the string data type can be identified with varying case: String or string. The former version relies on the using System directive, and the latter uses the string keyword. Both are valid C# references to the System.String data type, and the resultant Common Intermediate Language (CIL) code is unaffected by which version is chosen.

Implicit Using Directives

Readers will recall from Chapter 1 there was an ImplicitUsings element within the .csproj file for C# 10.0 and later:

<ImplicitUsings>enable</ImplicitUsings>

In addition, the source code consistently refers to things like Console, even though the fully qualified name is System.Console. The ability to abbreviate is afforded by the ImplicitUsings element, which tells the compiler to infer the namespace automatically rather than require the programmer to provide it. Using directives, therefore, allows the use of type identifiers without specifying their fully qualified name. To accomplish this, the complier generates global using directives whenever the ImplicitUsings element is set to enable.

Global Using Directives

If you search the subdirectory of a C# 10.0 (or higher) project, you will notice there is a file with the extension .GlobalUsing.g.cs, generally found in an obj folder subdirectory, and it contains multiple global using directives such as those found in Listing 5.9.

Listing 5.9: Implicit Usings Generated Global Using Declaratives3

// <auto-generated/>
global using global::System;
global using global::System.Collections.Generic;
global using global::System.IO;
global using global::System.Linq;
global using global::System.Net.Http;
global using global::System.Threading;
global using global::System.Threading.Tasks;

Each of these lines4 is a global using directive that tells the compiler to imply the namespace qualifier for any type that appears within the namespace specified. For example, global using global::System allows implicit using directives like Console.WriteLine("Hello! My name is Inigo Montoya!") rather than the fully qualified name System.Console.WriteLine(...) because Console is defined in the System namespace.

Of course, you can provide your own global using declaratives. Say, for example, you frequently are using the System.Text.StringBuilder class (initially introduced in Chapter 2). Instead of always referring to it by the fully qualified name, you can provide a global using directive for the System.Text namespace and then just refer to the type using the abbreviation StringBuilder (see Listing 5.10), also still relying on implicit usings for System.Console.

Listing 5.10: Implicit Using Directives with StringBuilder

// The global using directive imports all types from
// the specified namespace into the project
global using System.Text;
// ...
public class Program
{
    public static void Main()
    {
        // See Chapter 6 for explanation of new();
        StringBuilder name = new();
 
        Console.WriteLine("Enter your first name: ");
        name.Append(Console.ReadLine()!.Trim());
 
        Console.WriteLine("Enter your middle initial: ");
        name.Append( $" { Console.ReadLine()!.Trim('.').Trim() }." );
 
        Console.WriteLine("Enter your last name: ");
        name.Append($" { Console.ReadLine()!.Trim() }");
 
        Console.WriteLine($"Hello {name}!");
    }
}

The global using directives applies to the entire project regardless of in which file it appears. And, although C# allows the same global using declarative multiple times, doing so is redundant. For this reason, it is preferable to place all the global using directives into a single file named Usings.cs by convention. Collocating them here also provides a well-known location to place them or remove such declaratives.

While global using directives apply to the entire project, C# also supports using directives that apply only to the current file. The global using declarative, however, must appear before any other (non-global) using directives, which we cover after the .csproj using element.

csproj Using Element

It is also possible to specify global using declaratives within your project (.csproj) file with a Using element, as shown in Listing 5.11

Listing 5.11: Sample .NET Console Project File with Using Element

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net7.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>
  <ItemGroup>
    <Using Include="System.Net" />
    <Using Static="true" Include="System.Console"/>
  </ItemGroup>
</Project>

The important thing to note is that unlike the ImplicitUsings element, the Using element is a subelement to the ItemGroup element rather than the PropertyGroup element. And, given the Using element for System.Net specified, it is no longer necessary to fully qualify HttpClient, which is part of the System.Net namespace. Instead, the compiler will generate a global using System.Net directive when building the project. There is also another Using statement that includes a Static attribute on it, which we will explain further in the next section.

Using Static Directive

The using directive allows you to abbreviate a type name by omitting the namespace portion of the name—such that just the type name can be specified for any type within the stated namespace. In contrast, the using static directive allows you to omit both the namespace and the type name from any static member of the stated type. A using static System.Console directive, for example, allows you to specify WriteLine() rather than the fully qualified method name of System.Console .WriteLine(). Continuing with this example, we can update Listing 5.2 to leverage the using static System.Console directive to create Listing 5.13.

Listing 5.13: Using Static Directive

using static System.Console;
 
public class HeyYou
{
    public static void Main()
    {
        string firstName;
        string lastName;
 
        WriteLine("Hey you!");
 
        Write("Enter your first name: ");
        firstName = ReadLine() ?? string.Empty;
 
        Write("Enter your last name: ");
        lastName = ReadLine() ?? string.Empty;
 
        WriteLine(
            $"Your full name is { firstName } { lastName }.");
    }
}

In this case, there is no loss of readability of the code: WriteLine(), Write(), and ReadLine() all clearly relate to a console directive. In fact, one could argue that the resulting code is simpler and therefore clearer than before.

However, sometimes this is not the case. For example, if your code uses classes that have overlapping behavior names, such as an Exists() method on a file and an Exists() method on a directory, then a using static directive would reduce clarity when you invoke Exists(). Similarly, if the class you were writing had its own members with overlapping behavior names—for example, Display() and Write()—then clarity would be lost to the reader.

This ambiguity would not be allowed by the compiler. If two members with the same signature were available (through either using static directives or separately declared members), any invocation of them that was ambiguous would result in a compile error.

Note that C# 10 or later also support global static using directives such as:

global using static System.Console;

Similarly, a global using static directive can be configured in the csproj file:

<Using Static="true" Include="System.Console"/>

This is also shown in Listing 5.11.

Aliasing

Starting in C# 12.0, the using directive also allows aliasing a namespace or any type including tuples, pointers (Chapter 23), array types, and generic types (Chapter 12). An alias is an alternative name that you can use within the text to which the using directive applies. The two most common reasons for aliasing are to disambiguate two types that have the same name and to abbreviate a long name. In Listing 5.14, for example, the CountDownTimer alias is declared as a means of referring to the type System.Timers.Timer. Simply adding a using System.Timers directive will not sufficiently enable the code to avoid fully qualifying the Timer type. The reason is that System.Threading also includes a type called Timer; therefore, using just Timer within the code will be ambiguous.

Listing 5.14: Declaring a Type Alias

using CountDownTimer = System.Timers.Timer;                                                 
using StartStop = (DateTime Start, DateTime Stop);                                                 

public class HelloWorld
{
    public static void Main()
    {
        CountDownTimer timer;                                                               
        StartStop startStop;                                                                
        // ...
    }
}

Listing 5.14 uses an entirely new name, CountDownTimer, as the alias. It is possible, however, to specify the alias as Timer, as shown in Listing 5.15.

Listing 5.15: Declaring a Type Alias with the Same Name

// Declare alias Timer to refer to System.Timers.Timer to                                   
// avoid code ambiguity with System.Threading.Timer                                         
using Timer = System.Timers.Timer;                                                          
 
public class HelloWorld
{
    public static void Main()
    {
        Timer timer;                                                                        
 
        // ...
    }
}

Because of the alias directive, “Timer” is not an ambiguous reference. Furthermore, to refer to the System.Threading.Timer type, you will have to either qualify the type or define a different alias.

Of course, C# 10 and later also support global aliasing using directives such as:

global using Timer = Timers.Timer;

And like with all other global using directives, a global using alias directive can be configured in the csproj file:

<Using Include=" System.Timers.Timer" Alias="Timer"/>

InformIT Promotional Mailings & Special Offers

I would like to receive exclusive offers and hear about products from InformIT and its family of brands. I can unsubscribe at any time.

Overview


Pearson Education, Inc., 221 River Street, Hoboken, New Jersey 07030, (Pearson) presents this site to provide information about products and services that can be purchased through this site.

This privacy notice provides an overview of our commitment to privacy and describes how we collect, protect, use and share personal information collected through this site. Please note that other Pearson websites and online products and services have their own separate privacy policies.

Collection and Use of Information


To conduct business and deliver products and services, Pearson collects and uses personal information in several ways in connection with this site, including:

Questions and Inquiries

For inquiries and questions, we collect the inquiry or question, together with name, contact details (email address, phone number and mailing address) and any other additional information voluntarily submitted to us through a Contact Us form or an email. We use this information to address the inquiry and respond to the question.

Online Store

For orders and purchases placed through our online store on this site, we collect order details, name, institution name and address (if applicable), email address, phone number, shipping and billing addresses, credit/debit card information, shipping options and any instructions. We use this information to complete transactions, fulfill orders, communicate with individuals placing orders or visiting the online store, and for related purposes.

Surveys

Pearson may offer opportunities to provide feedback or participate in surveys, including surveys evaluating Pearson products, services or sites. Participation is voluntary. Pearson collects information requested in the survey questions and uses the information to evaluate, support, maintain and improve products, services or sites, develop new products and services, conduct educational research and for other purposes specified in the survey.

Contests and Drawings

Occasionally, we may sponsor a contest or drawing. Participation is optional. Pearson collects name, contact information and other information specified on the entry form for the contest or drawing to conduct the contest or drawing. Pearson may collect additional personal information from the winners of a contest or drawing in order to award the prize and for tax reporting purposes, as required by law.

Newsletters

If you have elected to receive email newsletters or promotional mailings and special offers but want to unsubscribe, simply email information@informit.com.

Service Announcements

On rare occasions it is necessary to send out a strictly service related announcement. For instance, if our service is temporarily suspended for maintenance we might send users an email. Generally, users may not opt-out of these communications, though they can deactivate their account information. However, these communications are not promotional in nature.

Customer Service

We communicate with users on a regular basis to provide requested services and in regard to issues relating to their account we reply via email or phone in accordance with the users' wishes when a user submits their information through our Contact Us form.

Other Collection and Use of Information


Application and System Logs

Pearson automatically collects log data to help ensure the delivery, availability and security of this site. Log data may include technical information about how a user or visitor connected to this site, such as browser type, type of computer/device, operating system, internet service provider and IP address. We use this information for support purposes and to monitor the health of the site, identify problems, improve service, detect unauthorized access and fraudulent activity, prevent and respond to security incidents and appropriately scale computing resources.

Web Analytics

Pearson may use third party web trend analytical services, including Google Analytics, to collect visitor information, such as IP addresses, browser types, referring pages, pages visited and time spent on a particular site. While these analytical services collect and report information on an anonymous basis, they may use cookies to gather web trend information. The information gathered may enable Pearson (but not the third party web trend services) to link information with application and system log data. Pearson uses this information for system administration and to identify problems, improve service, detect unauthorized access and fraudulent activity, prevent and respond to security incidents, appropriately scale computing resources and otherwise support and deliver this site and its services.

Cookies and Related Technologies

This site uses cookies and similar technologies to personalize content, measure traffic patterns, control security, track use and access of information on this site, and provide interest-based messages and advertising. Users can manage and block the use of cookies through their browser. Disabling or blocking certain cookies may limit the functionality of this site.

Do Not Track

This site currently does not respond to Do Not Track signals.

Security


Pearson uses appropriate physical, administrative and technical security measures to protect personal information from unauthorized access, use and disclosure.

Children


This site is not directed to children under the age of 13.

Marketing


Pearson may send or direct marketing communications to users, provided that

  • Pearson will not use personal information collected or processed as a K-12 school service provider for the purpose of directed or targeted advertising.
  • Such marketing is consistent with applicable law and Pearson's legal obligations.
  • Pearson will not knowingly direct or send marketing communications to an individual who has expressed a preference not to receive marketing.
  • Where required by applicable law, express or implied consent to marketing exists and has not been withdrawn.

Pearson may provide personal information to a third party service provider on a restricted basis to provide marketing solely on behalf of Pearson or an affiliate or customer for whom Pearson is a service provider. Marketing preferences may be changed at any time.

Correcting/Updating Personal Information


If a user's personally identifiable information changes (such as your postal address or email address), we provide a way to correct or update that user's personal data provided to us. This can be done on the Account page. If a user no longer desires our service and desires to delete his or her account, please contact us at customer-service@informit.com and we will process the deletion of a user's account.

Choice/Opt-out


Users can always make an informed choice as to whether they should proceed with certain services offered by InformIT. If you choose to remove yourself from our mailing list(s) simply visit the following page and uncheck any communication you no longer want to receive: www.informit.com/u.aspx.

Sale of Personal Information


Pearson does not rent or sell personal information in exchange for any payment of money.

While Pearson does not sell personal information, as defined in Nevada law, Nevada residents may email a request for no sale of their personal information to NevadaDesignatedRequest@pearson.com.

Supplemental Privacy Statement for California Residents


California residents should read our Supplemental privacy statement for California residents in conjunction with this Privacy Notice. The Supplemental privacy statement for California residents explains Pearson's commitment to comply with California law and applies to personal information of California residents collected in connection with this site and the Services.

Sharing and Disclosure


Pearson may disclose personal information, as follows:

  • As required by law.
  • With the consent of the individual (or their parent, if the individual is a minor)
  • In response to a subpoena, court order or legal process, to the extent permitted or required by law
  • To protect the security and safety of individuals, data, assets and systems, consistent with applicable law
  • In connection the sale, joint venture or other transfer of some or all of its company or assets, subject to the provisions of this Privacy Notice
  • To investigate or address actual or suspected fraud or other illegal activities
  • To exercise its legal rights, including enforcement of the Terms of Use for this site or another contract
  • To affiliated Pearson companies and other companies and organizations who perform work for Pearson and are obligated to protect the privacy of personal information consistent with this Privacy Notice
  • To a school, organization, company or government agency, where Pearson collects or processes the personal information in a school setting or on behalf of such organization, company or government agency.

Links


This web site contains links to other sites. Please be aware that we are not responsible for the privacy practices of such other sites. We encourage our users to be aware when they leave our site and to read the privacy statements of each and every web site that collects Personal Information. This privacy statement applies solely to information collected by this web site.

Requests and Contact


Please contact us about this Privacy Notice or if you have any requests or questions relating to the privacy of your personal information.

Changes to this Privacy Notice


We may revise this Privacy Notice through an updated posting. We will identify the effective date of the revision in the posting. Often, updates are made to provide greater clarity or to comply with changes in regulatory requirements. If the updates involve material changes to the collection, protection, use or disclosure of Personal Information, Pearson will provide notice of the change through a conspicuous notice on this site or other appropriate way. Continued use of the site after the effective date of a posted revision evidences acceptance. Please contact us if you have questions or concerns about the Privacy Notice or any objection to any revisions.

Last Update: November 17, 2020