In .Net, the namespace is always an integral part of the name of each type. However, if you needed to specify the full namespace every time you declare a certain type, this would cause a huge repetition and noise in the code. The using directive is used for this; it essentially brings all the prefixes into one place, forcing the "last" section of the type to be specified. This can only be done if there is no ambiguity.
However, the compiler does not care about this. Thus, there is a precompilation stage where each type declaration that relies on the using directive gets its prefix back.
So when you say:
Using System; void foo() { String s1 = "bla"; String s2 = "bli"; }
What happens during precompilation is that a System namespace is added to each String declaration, for example:
void foo() { System.String s1 = "bla"; System.String s2 = "bli"; }
And only now the compiler really enters.
So, about performance, technically, it can affect the performance of the build process. The more you get, the more matches you need to complete at the pre-compilation stage: therefore, the compiler sees String . What is this String ? Is it System.String or is it SomeOtherNamespace.String ? What really happens is that the compiler adds every namespace that it finds when used to the type declaration and checks to see if that type exists. If so, great, if not, he will try the next namespace.
So, you see that if you have a lot of files with unused using declarations, the compiler will definitely do the redundant work. In extreme cases, this can significantly degrade the performance of the assembly itself.
In general, never be shy about using something that you are using (no pun intended). But you should avoid declaring unnecessary using directives, not only because of the potential (unlikely) performance impact on build time, but also because you want your code to be as clean as possible.