Once again, in this series of posts I look at the parts of the .NET Framework that may seem trivial, but can help improve your code by making it easier to write and maintain. The index of all my past little wonders posts can be found here.
Visual Studio 2015 is on the horizon! In fact, some of you may already have played with the preview and seen some of the many neat new things to come – both in the IDE and in the C# language.
For those who haven’t been keeping up with the announcements, I’m taking some blog time for a few Little Wonders posts to talk about some of the neat new things that will be in C# 6.
Note: All of the C# 6 features mentioned are current with the latest CTP of VS2015 as of the time of this writing. The syntax and exact feature behaviors may be subject to change in the final released version.
Importing a whole namespace with “using”
Of course, we all know that you can import a namespace with using. This gives us the ability to use a type with just the type’s name in our code. That is, it allows us to use the type name directly without the need of fully qualifying it with it’s namespace.
For example, if we didn’t import the System namespace, we’d have to say:
public class Driver
{
public static void Main()
{
// without importing a namespace, we'd have to fully qualify the type
// Console as System.Console
System.Console.WriteLine("Hello, World!");
}
}
But, of course, we can import the System namespace, so that allows us to shorten the call to just:
using System;
public class Driver {
public static void Main() {
Console.WriteLine("Hello, World!");
}
}
This eliminates a lot of redundant “System.” prefixes in our code. But this is all old stuff, why bring it up? Mostly, I wanted to set the stage for what using does today so I can discuss what changes have been made with the new using static directive in C# 6.
Importing a static class with “using static”
Now, in C# 6, we can go one step further and import the static members of a class into our namespace. This means we can use the static members of a class directly with no need to qualify them with their namespace or type name!
The format is “using static” followed by the type whose static methods you wish to import. For example, our short example before now becomes:
using static System.Console;
public class Driver {
public static void Main() {
// Now, the System.Console static class is imported, so we
// can use WriteLine directly
WriteLine("Hello, World!");
}
}
This may seem trivial, but it can eliminate a lot of redundant or superfluous type identifiers in the code and thus help improve readability (if used appropriately).
Note:In previous previews, the format was simply using without the static keyword, and only worked on static classes. In the current preview, the format has changed to using static and can import static members of any type (class, struct, enum).
Think, for example, of static classes like Math where it is simply a collection of mathematical functions. The “Math.” prefix really doesn’t add much to the readability because we know Sqrt() is a math function, so we can drop it with a using static System.Math like this:
using static System.Console;
using static System.Math;
public class Driver {
public static void Main() {
// Now we can access Sqrt directly since we imported System.Math
WriteLine("Hello, World: the square root of 4 is " + Sqrt(4));
}
}
Or consider static classes like Enumerable that have a lot of nice static methods like Range() and Repeat(). Again the “Enumerable.” prefix doesn’t add much to the readability, so why not drop it with a static import?
using static System.Linq.Enumerable;
public class Driver {
public static void Main() {
// Now, Enumerable.Range() can just become Range()
var nums = Range(1, 10).ToArray();
...
}
}
As you can see, this shortens the body of our code and eliminates unnecessary identifiers. Obviously, you’ll want to use this with care. There are probably some instances where including the type name improves readability (that is, if you can’t easily tell the original of the method without it from the context). As such, make sure you use good judgment on when it improves readability and when it doesn’t.
Limiting Extension Method visibility with “using static”
Here’s one very big reason I’m excited about using static: I love extension methods. I do not love abusing them, but I do love well designed extension methods and think they can really improve your code if used judiciously. The problem with extension methods is that even the well-written ones can pollute your namespace (and IntelliSense) if you have a lot of them extending some of the more common types (like string or object).
One way to limit this impact would be to put your extension methods into very compartmentalized namespaces and only import the namespace you want.
For example, let’s say I have a namespace called Utilities.Extensions and under it I have extensions for:
- Preconditions – extensions to allow me to create test preconditions much like Google Guava in Java
- Strings – extensions to allow me to check strings for certain formats
- Type – extensions for querying properties of types
- etc.
If all of these static classes with their extensions were in the same namespace, and I did an import such as:
// imports the whole namespace including all extension methods
using Utilities.Extensions;
Then all of the extension methods becomes implicitly visible whether I want them or not. It would be nice to isolate them. So I could put each of the static classes in their own namespace, but then I’d have namespaces for Utilities.Extensions.Preconditions just to hold a Preconditions static class, which seems a bit redundant.
Instead, I can now take advantage of using static and just include the extension methods from the class that I want, which will only make those extension methods visible without an explicit reference:
// only Preconditions and it's extension methods will be visible
using static Utilities.Extensions.Preconditions;
Now, only the extension methods in Preconditions will be visible without an explicit reference, and all the other extension methods in Utilities.Extensions will not be imported.
Importing enum constants with “using static”
As I alluded to before, in the current preview you can also import the static members of any type, not just static classes. This means you can import the constants of an enum (static by definition) so you do not need to explicitly qualify them.
Consider if you wanted to do a lot of console output with multiple colors. You’d make use of the System.Console class and the System.ConsoleColor enum. This would mean that you’d have to use a lot of code like:
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("This is my output in red");
Console.ForegroundColor = ConsoleColor.White;
Console.WriteLine("This is my output in white");
Console.ForegroundColor = ConsoleColor.Blue;
Console.WriteLine("This is my output in blue");
Now, we know we can eliminate the “Console.” with a using static System.Console, but we can also eliminate the need to qualify the constants of the enum by performing a using static System.ConsoleColor as well, this would shorten it to
ForegroundColor = Red;
WriteLine("This is my output in red");
ForegroundColor = White;
WriteLine("This is my output in white");
ForegroundColor = Blue;
WriteLine("This is my output in blue");
This eliminates a lot of very redundant qualifiers that don’t really improve the quality of the code.
Summary
The new using static directive allows us to import the static members of a type without needing to qualify them with their type name. This can help improve readability and maintainability in your code. Of course, as with any syntactical sugar, you should be careful not to abuse this power. If the addition of the qualifying type name actually improves the readability of the code, then by all means keep it. But for cases where the qualifying type name becomes redundant or superfluous, feel free to utilize the new using static to eliminate the need to explicitly state it.
Thanks for reading and stay tuned for more features of C# 6!