168

I'm having a look at a couple of the new features in C# 6, specifically, "using static".

using static is a new kind of using clause that lets you import static members of types directly into scope.
(Bottom of the blog post)

The idea is as follows, according to a couple of tutorials I found,
Instead of:

using System;

class Program 
{ 
    static void Main() 
    { 
        Console.WriteLine("Hello world!"); 
        Console.WriteLine("Another message"); 
    } 
}

You can omit the repeated Console statement, using the new C# 6 feature of using static classes:

using System.Console;
//           ^ `.Console` added.
class Program 
{ 
    static void Main() 
    { 
        WriteLine("Hello world!"); 
        WriteLine("Another message"); 
    } // ^ `Console.` removed.
}

However, this doesn't appear to be working for me. I'm getting an error on the using statement, saying:

"A 'using namespace' directive can only be applied to namespaces; 'Console' is a type not a namespace. Consider a 'using static' directive instead"

I'm using visual studio 2015, and I have the build language version set to "C# 6.0"

What gives? Is the msdn blog's example incorrect? Why doesn't this work?


The blog post has now been updated to reflect the latest updates, but here's a screenshot in case the blog goes down:

blog

Cerbrus
  • 70,800
  • 18
  • 132
  • 147

2 Answers2

236

It appears the syntax has slightly changed since those blog posts were written. As the error message suggests, add static to your include statement:

using static System.Console;
//      ^
class Program 
{ 
    static void Main() 
    { 
        WriteLine("Hello world!"); 
        WriteLine("Another message"); 
    } 
}

Then, your code will compile.


Note that, in C# 6.0, this will only work for members declared as static.

For example, consider System.Math:

public static class Math {
    public const double PI = 3.1415926535897931;
    public static double Abs(double value);
    // <more stuff>
}

When using static System.Math, you can just use Abs();.
However, you'd still have to prefix PI because it isn't a static member: Math.PI;.

Starting with C# version 7.2, this shouldn't be the case, const values like PI can be used as well.

Cerbrus
  • 70,800
  • 18
  • 132
  • 147
  • 3
    I'm having a similar problem, but instead with `System.Math`, specifically `Math.PI`. When I use `using static System.Math`, methods like `Sqrt()` work but not a constant like `PI`. I have to continue writing `Math.PI` or the code doesn't compile. I'm curious as to why this doesn't work. Should I submit a new question for this? – skwear Sep 22 '16 at 20:05
  • 6
    @skwear: that sounds like material for a new question, yea. – Cerbrus Sep 22 '16 at 20:41
  • 2
    As a quick answer to @skwear's question: _"using static is a new kind of using clause that lets you import __static__ members <...>"_. `PI` is not a _static_ member of the `Math` class. It's a constant. Simply put: the member has to be declared as `static`. – Cerbrus Apr 05 '17 at 09:54
  • 3
    Sounds like an opportunity for a new syntax like: `using const System.Math;` :) – Filip Skakun Nov 17 '17 at 00:05
  • A better fix would be for the compiler to treat public constants as static. After all, they are used via the same syntax. :) – ToolmakerSteve Dec 23 '17 at 14:19
  • @DaveCousineau: I've updated the last line a little. Better? – Cerbrus Feb 28 '18 at 17:26
  • @Cerbrus no, you fixed the part that I'm actually not 100% sure of. I said "const is static", but reading about it, I'm not sure that's correct to say. Regardless, you *can* import `PI` and other consts. I'm guessing this was a limitation of previous versions of C#, since this question is tagged as C# 6. With C# 7.2 I am able to use `PI` instead of `Math.PI`. – Dave Cousineau Feb 28 '18 at 17:31
  • Ah, I'll look into this tomorrow, when I am on my DEV machine again. – Cerbrus Feb 28 '18 at 17:33
  • 1
    The example in the Microsoft documentation claims PI can be used without prefix: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/using-static – Guney Ozsan Aug 07 '18 at 23:35
  • @GuneyOzsan: That wasn't the case when I wrote this answer. – Cerbrus Aug 07 '18 at 23:37
  • 1
    @Cerbrus Thanks for the detail. Looks like they later noticed the inconvenience and contradiction:) – Guney Ozsan Aug 09 '18 at 11:32
  • One important point to consider with `using static` - it doesn't work for extension methods. – Matt Arnold Nov 26 '20 at 14:18
  • @MattArnold why would it? What use case would there be for `using static` with extension methods? – Cerbrus Nov 26 '20 at 14:20
  • I had an extension method on a `Func` but then later realized when I went to call it, it couldn't infer that a lambda of that type was of that type; so, to save changing the signature and potentially breaking other calling code, I wanted to call it like a normal static method but without the static class qualifier (e.g. `MyExtensionMethod(@string => new CustomResponse(@string))`). – Matt Arnold Nov 26 '20 at 18:43
4

The static Keyword on a using statement will import only the one, specified type (and it's nested types). Furthermore you must not give the type name anymore. So just add static to your using.

Note: Please use this feature only when the two classes are logically closely related, otherwise it makes reading the code pretty hard.

Tobias Brohl
  • 479
  • 6
  • 25