Why are unused using directives not a warning?

Why are unused using directives not a warning?

Rate This
  • Comments 56

As I’ve discussed before, we try to reserve warnings for only those situations where we can say with almost certainty that the code is broken, misleading or useless. One reason for trying to ensure that warnings are not “false positives” is that we don’t ever want to encourage someone to take working, correct code and break it so as to remove the warning. Another is that since many people compile with “warnings are errors” turned on, we do not want to introduce a whole lot of unnecessary build breakages should the warning turn out to be unwarranted.

An unused using directive is almost certainly not “broken”, and it’s probably not misleading. It certainly is useless though. Why not produce a warning for this, so that you can remove the useless directive from your program?

Suppose we make an unused using into a warnings. Suppose you do have “warnings are errors” turned on. And suppose you create a new console project in Visual Studio.  We generate you this code:

using System;
using System.Text;
using System.Linq;

class Program
{
  static void Main(string[] arguments)
  {
  }
}

… which doesn’t compile. Which is better, generating code that doesn't compile, or omitting the using directives and making you type "using System;" the first time you try to use Console.WriteLine?

Either way is a really bad user experience. So, no such feature.

  • "Which is better, generating code that doesn't compile, or omitting the using directives and making you type "using System;" the first time you try to use Console.WriteLine?"

    Umm, the latter. I have already edited all of the major project and item templates that come with Visual Studio (which should really be a lot easier, btw) to remove the superfluous using statements; I am going to do it again when Visual Studio 2010 goes RTM. Why would Visual Studio assume that I am going to use Console.WriteLine in *every single class* that I create? Most of the time I don't need the System namespace at all, and the other namespaces are even less likely. And even if I do end up needing it, it is trivial to select "Resolve" from the context menu and have it added for me.

    Contrary your assertion, I DO find unused namespaces to be misleading, just like unused types, members, or local variables. They are a sign to me that code has been modified and not properly reviewed. The difference between namespaces and the other code elements is that with the other elements, you cannot be sure that they are not being accessed through reflection; but with namespaces (and type aliases for that matter) you KNOW whether or not they are being used.

    I agree with Danyel: I have "warnings as errors" turned on because I WANT to be warned when there is a potential problem with my codebase. Why the C# team is so intent on not warning me, when that is specifically what I have asked for, really bewilders me. That illogical line of reasoning has been used to justify not adding all sorts of very useful warnings.

    As for the rest of the discussion, I strongly agree with all of Jon Skeet's points, except for event handler names, where I agree with Pavel. But the others are all long-standing annoyances I have with Visual Studio. It is even more annoying when posts like this one hold up my annoyances as virtues and then use them to justify not adding other useful features. As Jon said: "I can see that the decision not to produce warnings for useless code makes some sense in the light of Visual Studio *encouraging* you to have useless code." I would love to see a push in the next version of VS for EVERY single area of the IDE to start encouraging good practices, instead of catering to the lowest common denominator.

  • @TaylorMichaelL,

    Xml comments are parsed by the compiler. If a namespace is used in the xml comments, it is not unused, and should not generate the warning.

  • It may be worth pointing out that an unused using directive *may* mean a bug in your code. It may be that you're using an extension method from namespace A instead of the one you intended to use from namespace B. Admittedly this is partly due to one of my very few peeves about how C# has evolved (the way that extension methods are discovered) but it really could change behaviour.

  • Naming Conventions:

    If your first form is called MainForm, is your second form called MainForm1?  You have the same issue, namely that the IDE developers are probably NOT psychic.  (Correct me if I'm wrong.)  They wouldn't follow this age-old convention if it didn't satsify the general market.

    The numeric suffix conveition has been around since before most fresh-out-of-school coders were born and is used in the vast majority of software tools name their objects using the "type + index" convention, including 3-D software.  I'd assemble a list upon request, but Eric probably doesn't want me filling up his allocated blog space.

    Personally, I will end up renaming my controls no matter what Microsoft calls them, just as I do with Photoshop layers, 3ds max edit objects, etc. etc..  The idea is, protoype fast, beautify when it matters.

    Directive Warnings:

    I second the suggestion to use the Message box.  It's practically useless right now anyway.

    If you think unused usings are bad, try collapsing the block and see how quickly you forget about them.

    Even Visual Studio 2008 Standard *without* SP1 has the option to right-click, Organize Usings, Remove Unused Usings.  How any self-respecting coder could miss this is beyond me.  Methinks you should explore and understand the tools you use on a day-to-day basis to feed your family before you complain about a feature that already exists.

    Bear in mind that VS only creates usings for existing references.  If you removed unwanted references when you first create your project, you won't get all those extraneous directives in every code module you add.  The problem is when you remove a reference mid-development, and all those extra usings you were never warned about suddenly become errors.  That's where right-click | Organize Usings is very handy.

  • To amend myself, I don't know if VS2005 or VS2003 have the Organize Usings option out of the box, as it's been quite a while since I've used either of them.  I apologize to the folks still using the older IDE's.  As mentioned before, you have Power Commands and other tools at your disposal.  If you don't like adding extra tools, upgrade to VS2008.  If you're not using VS at all . . . good luck to you.

  • @Tom: "Even Visual Studio 2008 Standard *without* SP1 has the option to right-click, Organize Usings, Remove Unused Usings.  How any self-respecting coder could miss this is beyond me." - which is why I specifically said "throughout a project" (although what I really meant was throughout a solution). With a large codebase the idea of opening up hundreds of .cs files and right clicking each one is ridiculous. It's nice to have it in the code editor but it'd be much nicer to have it globally.

  • @Tom,

    "Bear in mind that VS only creates usings for existing references.  If you removed unwanted references when you first create your project, you won't get all those extraneous directives in every code module you add."

    This is a complete fabrication. If I remove the extraneous System.Data and System.Xml references when I initially create a project, then not only will the extraneous using statements still be there when I add another class, but Visual Studio will actually *add* the references that I already removed! Which is why I edited the default templates to get rid of that nonsense.

  • It'd be annoying if I temporarily commented out some code and then started getting warnings about the now-unused Using statements.

  • @Andy: You'll get exactly the same thing if you remove all uses of a local variable, but not the declaration. In the case of using directives it's extremely easy to get rid of that warning though - or you could just ignore it, if the commenting out really is temporary.

  • Seems the most obvious (and easiest?) solution is to enabled severity levels for code analysis rules (this would definitely be one) and make "Unused Using Statements" report as Information.  The Error List already supports these levels, so why not use them.

    As an extension of this would allow filtering which rules are reported as errors and which remain warnings when "warnings as errors" is set.

    Just my two cents.

  • Not always unused usings are really unused. Parts of codes that are not being compiled due to macro directives #IF may need those "unused" usings when they actually being compiled.

    Resharper can clean the unused usings (and other unused code parts) automatically throughout solution for you, btw.

Page 4 of 4 (56 items) 1234