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.

  • Although somewhat unrelated, this reminds me of a VS feature I wish existed. It would be nice if VS had an option to generate a using statement when tab-completing a namespace via Intellisense. At least I don't think this functionality exists...

  • I'd like a way to automatically remove all unused usings throughout a project - but it may already exist and I just haven't found it yet.

    The thing I'd definitely like using-wise, that VS definitely doesn't already do, is find potential "using"s that would provide an extension method that you are trying to use - the same way it provides potential "using"s that would match a class name if you type one in. This applies both to extension methods I've written myself, and to the extension methods in System.Linq that provide the query pattern for IEnumerable and company if you try to start typing a from iEnumerable select ... statement.

    I realize that doing that would be a fair amount of work for the intellisense engine - it's a lot easier to do some work on every unmatched classname than to do it on every unmatched method, I guess. But extension methods are rare - you could build a name->method mapping up front of every extension method defined in every assembly that the compiler is aware of, same as the way it must currently build a dictionary of name->class for every assembly to enable the 'add using' feature that already works. The dictionary of extension methods would be much smaller than the one that already exists for classes...

  • Yes, other IDEs handle this kind of thing fairly elegantly. I'm thinking specifically of editing Java in Eclipse, where the code completion knows about types in packages you haven't yet imported and adds them for you when copy and pasting, that sort of thing. I think some people write programs that NEVER call Console.WriteLine!

  • @Stuart: it's not there out of the box, but it's fairly trivial to script one. E.g. see this:

    http://blogs.msdn.com/djpark/archive/2008/08/16/organize-usings-across-your-entire-solution.aspx

  • And it would be nice if it were easier to configure which warnings were errors in VS too...

  • Guys - here are a couple of tips for the requested functionality mentioned above in VS 2008.

    To automatically add required "using" statements, click on the offending type name in the source code and watch for the small red line that appears under the last charactter of the type name and click <Ctrl>-<Period>. This brings up a context menu that will either add the required "using" statement or spell out the full namespace definition.

    To removed unused "using" statements, just right-click one of the using statements in your source code and click "Organize Usings" | "Remove Unused Usings".

    Hope that helps someone! Best wishes to all.

  • So the problem here is really that “warnings are errors” doesn't make sense if the warning is about "useless" code.  Could that feature be updated to understand which warnings are just about "useless" code and not treat those warnings as errors?

  • I've never worried about any of this since I started using ReSharper.

    It has:

    * Generate a using statement when tab-completing a namespace via Intellisense

    * Find potential "using"s that would provide an extension method that you are trying to use

    * Knows about types in [assemblies] you haven't yet imported and adds them for you when copy and pasting (OK, not quite seamless: requires some Alt+Enter keypresses)

  • Perhaps another type of compiler output is needed, something like Recommendations?

  • @stuart & Pavel:  There's also the VS 2008 Power Commands that adds Organize&Remove using among other useful extensions:

    http://code.msdn.microsoft.com/PowerCommands

  • I think this is another example of "good design is the art of making good compromises", and this is the right compromise to make.  For me, the difference between unused using directives and other types of compiler warnings is that (AFAIK) unused using directives have no impact on the generated IL, whereas other warnings serve to tell you that the compiler may ignore some of your code because it isn't reachable, unused, etc...

    @Eric,

    Were using statements such as "using IntFunc = Func<int>;" also included for this?  I could see this being treated differently than the "you didn't actually use types from the System namespace" case.  For me, the aliasing using case sits somewhere between this case and the used variable case.

  • It sounds like the problem in your example is that the sample code includes system.linq and system.text for some reason, even though I'm not using either. If I have set 'warnings are errors', then I WANT warnings to hurt.

  • One example where you would need them, that tools seem unable to comprehend, is when using conditional compilation.

    #if ALLOW_FILEIO

    using System.IO;

    #else

    using MyApp.FakeIO;

    #endif

  • @Danyel is spot on in my view.

    <rant>

    Why do the Visual Studio templates feel the need to include so many using directives? In my experience it's extremely easy to add a using directive automatically - I can't remember the last time I wrote one manually... probably back in VS2003.

    This is just one example of Visual Studio being annoying, in my opinion. Other examples:

    - Defaulting to creating "Form1.cs" - who actually *wants* a type called Form1? Ask me for a better name, or use a better default.

    - Defaulting to copying a file as "OriginalName - Copy.cs" - again, I'm bound to want to give it a different name, so ask me at the point of copying... and then rename the class within, if it matched the original name.

    - Defaulting to creating variables such as "textBox1" via the designer

    - Defaulting to creating event handlers such as "button1_Click"

    - Defaulting to adding references to various assemblies I rarely use (System.Data and System.Xml). I suppose this is somewhat justified by earlier versions of Visual Studio taking an age to bring up the "Add reference" dialog, which is much impoved in VS2010.

    All of these make it really easy to create an app which is ugly (in terms of code) at the expense of making it easy to create an app with meaningful names. Why not guide developers towards using meaningful names to start with, instead of it being a manual extra step?

    </rant>

    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... and with so much code already written, it's probably too late to fix it now. It does make me sad though... oh well, at least Resharper lets me remove unused using directives fairly easily.

    Sorry to be such a curmudgeon on this score. I promise to revert to my normal happy self soon.

  • I agree with Todd Wilder above.  

    It would be nice to have another type of compiler message that pointed out if a "using" or anything else were not actually necessary.  

    Maybe we can call the type of message "random musings of the compiler..."!

Page 1 of 4 (56 items) 1234