C#6: Using Static Types and Extension Methods

This week I thought I would continue from the last couple of posts on the new language features introduced in C#6 and look at the changes to the using keyword.

Up until the latest syntax, using was overloaded in three different ways1.

  1. To import types from a specific namespace, reducing the need to fully quality those types when referencing them in subsequent code.
  2. To alias namespaces and types in order to resolve ambiguities when types share a name but different namespaces.
  3. To define a scope at the end of which an object will be disposed

With C#6 comes an additional overload that allows us to import methods from within a specific static class. By specifying the static keyword after using, we can give the name of a static class containing the members we want to import. Doing this allows us to reference the methods as though they were members of our class.

Using Static

Consider System.Math; prior to this updated syntax, using the various methods on the System.Math class would require either specifying the fully qualifed type name, System.Math or, if using System were specified, just the type name, Math. Now, by specifying using static System.Math we can reference the methods of the Math class as though they were members of the class invoking them (without a System.Math or Math prefix). In this example, Math.Abs() is called as just Abs().

As with other additions in C#6, this seems to be aimed at improving developer productivity as it leads to less overall typing when using the methods of a static class. However, the new using static syntax also allows for very targeted inclusion of static classes without the rest of their containing namespace, previously only possible with an alias, such as using Math = System.Math. This targeting ability, while not really adding anything for regular static methods, makes a significant difference for extension methods.

Extension Methods

As you probably know, extension methods are just fancy static methods, they can even be invoked as would a regular static method. However, extension methods can also be invoekd as though they where member methods of a variable or literal value. For example, both the following examples compile to the same code (assuming we have an enumerable called list).

However, before the using static syntax, including extension methods was a bit uncontrolled. If you wanted the extension methods in System.Linq.Enumerable, you had to include the entire System.Linq namespace; there was no way to include only the Enumerable static class. In some circumstances, this inability to include just the static class led to annoying type name clashes and occasionally unexpected overload resolution ambiguities or surprises. Now, with using static we can specify the exact class of extension methods we want to include and ignore the rest of the containing namespace.

With all that said, there is a notable difference between including regular methods of a static class and extension methods of a static class when importing via using static <namespace>.<static class>2.

Subtle Difference

When a static class is imported with using static, the way a method can be invoked depends on whether it is an extension method or not. For example, imagine we have a static class called MyStaticClass and it has a regular3 static method on it called Print that takes a string. When included via using static, Print could be used like this:

However, if instead Print were an extension method on type string, including MyStaticClass via using static would limit Print to being used like this:

Note how in both examples , Print can be invoked as a traditional static method when the containing type is referenced, as in MyStaticClass.Print(), but their invocation varies when using static imports the class. In that second scenario, non-extension static methods are invoked as though they are methods on the current type, where as extension methods are invoked only as though they are methods on a variable. For the extension method version of Print, the following is not allowed:

To use this argument-style syntax with an extension method, we must resort to the same syntax we would have used before using static, specifying the type name before the method:

Though I feel it is clear and intuitive, this is a subtle difference worth understanding, as it can lead to breaking changes. Consider if you were refactoring the methods of a static class from extension method to regular static method or vice versa, and that class were imported somewhere with using static; any invocations that were not prefixed with the static class name would fail to compile.

In Conclusion

Overall, I like the new using static syntax; I believe the differences in method invocation from how static class methods are normally invoked makes sense and I hope you do too. Like all the other features of C#, there will be times to use this feature and times to let it go in favour of something clearer and more appropriate. For me, the ability to pluck a specific class and its extension methods from a namespace without importing the rest of that namespace is the most useful aspect of using static and probably what I will use most. How about you? Do you see yourself adding using static to your coding arsenal, or is it going to languish in your scrapbook of coding evil? Do tell.

  1. The MSDN docs say two different ways, but it was clearly three and is now three and a halfish 

  2. However, unlike the subtle difference I highlighted in my last post, thankfully, the compiler will catch this one 

  3. as in not an extension method 

3 thoughts on “C#6: Using Static Types and Extension Methods”

Leave a Reply

Your email address will not be published. Required fields are marked *