In this article, we’re going to learn about the using static directive feature in C#.

To download the source code for this article, you can visit our GitHub repository.

Let’s dive in.

What Is a “using static” Directive?

In C# 6, the using static directive was introduced to reduce the boilerplate code when accessing the static members of a type:

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

Once we name a type with the using static directive, we can reference the static members and nested types of the <fully-qualified-type-name> without using its name.

Support Code Maze on Patreon to get rid of ads and get the best discounts on our products!
Become a patron at Patreon!

Let’s look at how we can access the different types of static members with the using static directive.

Another great “using” directive usage is the “global using” directive so make sure to check our article about Global Using Directives in C# if you’re interested.

Methods and Properties

Let’s create a sample class ClassA with two static methods MethodA() and MethodB():

public static class ClassA
{
    public static void MethodA() { }
    public static void MethodB() { }
}

In order to invoke these methods, we usually call them by their class name:

ClassA.MethodA();
ClassA.MethodB();

Here, we’re repeating the class name ClassA for invoking its static members every time. If we have to call the static members in many places, then the codebase will become too verbose.

But, with this feature, we can directly call the static methods without using their class name every time.

For that, we first need to name the type ClassA with the using static directive:

using static ClassA;

MethodA();
MethodB();

After that, we can directly call the static methods MethodA() and MethodB(). Similarly, we can access the static properties and fields.

Enums

Accessing the enum items directly without using the enum type name is also possible. Let’s create an enum Role with two items User and Admin:

public enum Role
{
    User,
    Admin
}

Usually, we would’ve accessed the enum items by their type name:

Role role = Role.User;

If we’re about to use the enum items in multiple places, then we can import the items with using static Role:

using static Role;

Role role = User;

Now, we can refer to the enum item User or any other without using its enum name.

Constants

In the same way, we can also directly access the constants. Let’s create a class Status with a few constants:

public class Status
{
    public const string Pending = "Pending";
    public const string InProgress = "InProgress";
    public const string Completed = "Completed";
}

To access these constants, we first need to name the type Status with the using static directive:

using static Status;

And then, we can directly access the constants Pending, Completed:

var pending = Pending;
var completed = Completed;

Nested Type Members

We can call the nested type’s static members in a similar way. Let’s create the nested type ClassB within ClassA. The nested type has two methods MethodA() and MethodB():

public class ClassA
{
    public class ClassB
    {
        public static void MethodA() { } 
        public static void MethodB() { }
    }
}

In order to call these methods, we usually end up calling them by prefixing the entire nested class hierarchy:

ClassA.ClassB.MethodA();
ClassA.ClassB.MethodB();

We can see that it is too verbose as we are repeating ClassA.ClassB every time to invoke the methods MethodA() and MethodB() of the nested class.

To overcome this, we can import the nested type members by the using static feature and call them directly. In order to do so, we first need to name the nested type ClassA.ClassB with the using static directive:

using static ClassA.ClassB;

MethodA();
MethodB();

After that, we can call the methods MethodA() and MethodB() directly.

Or else, we can only name the ClassA with using static directive and then access the ClassB methods as ClassB.MethodA() and ClassB.MethodB():

using static ClassA; 

ClassB.MethodA();
ClassB.MethodB();

Extension Methods

Extension methods are available for lookup if they are anywhere in the same namespace. But if it’s in a different namespace, we can name its type with the using static directive and start using the extension methods.

Let’s create a static class NumberExtensions with an extension method Add() that will add two numbers in NamespaceA:

namespace NamespaceA;

public static class NumberExtensions
{
    public static int Add(this int number1, int number2)
    {
        return number1 + number2;
    }
}

Once, we name the class NumberExtentions with the using static directive, then the extension method Add() is available for lookup on its type int in NamespaceB:

using static NamespaceA.NumberExtensions;
namespace NamespaceB;

var sum = 1.Add(2);

But it’s not possible to invoke it like a regular method using this feature:

NumberExtensions.Add(1, 1); // Valid

// Error CS0103 
// The name 'Add' does not exist in the current context
Add(1, 1);

NumberExtensions.Add() is a valid method call when called by its class name. However, it’s not possible to call the Add() method directly by using the using static directive. This applies only to extension methods.

Base Class Members

Using this feature, we cannot import the base class’s static members. Let’s create a base class ClassA with one static member MethodA() and a derived class ClassB with a static method MethodB()

public class ClassA
{
    public static void MethodA() { }
}

public class ClassB : ClassA
{
    public static void MethodB() { }
}

After importing the static members of ClassB, we can call the MethodB() without any errors.

But, if we try to call the base class method MethodA(), we get a compiler error:

using static ClassB;

// Valid
MethodB();

// Error CS0103
// The name 'MethodA' does not exist in the current context
MethodA();

Ambiguity Considerations With “using static” Directive

If we import static members of two different types with using static, we need to ensure that the method signatures are unique among those types. Otherwise, the compiler will throw an error if we try to access the method with the same signature.

Let’s create two classes ClassA and ClassB with the same method signature void Method():

public class ClassA
{
    public static void Method() { }
}

public class ClassB
{
    public static void Method() { }
}

If we call this method when two of these classes are named with using static directive, then compile time error will be thrown:

using static ClassA;
using static ClassB;

// Error CS0121
// The call is ambiguous between the following methods or properties: 'ClassA.Method()' and 'ClassB.Method()'
Method();

Hence, we need to ensure that the method signatures are unique among the imported types.

Conclusion

In this article, we’ve learned all about using static directive and their usage. This is a great feature and comes in handy when we want to reduce the verbosity of the frequently accessed static members.

Liked it? Take a second to support Code Maze on Patreon and get the ad free reading experience!
Become a patron at Patreon!