BRO1126: Using directives should be qualified¶
A using directive inside a namespace names its namespace or type fully. Replaces StyleCop SA1135. Only relevant when usings go inside the namespace (StyleCop's SA1200 default; the preset puts them outside).
Example¶
Before¶
namespace System.Reporting
{
using IO;
using Builder = Text.StringBuilder;
public class Export
{
public Builder Lines { get; } = new Builder();
public FileInfo? Target { get; set; }
}
}
After¶
namespace System.Reporting
{
using System.IO;
using Builder = System.Text.StringBuilder;
public class Export
{
public Builder Lines { get; } = new Builder();
public FileInfo? Target { get; set; }
}
}
Why¶
Inside a namespace, using IO; means something different depending on the namespace around it, so moving the code or
renaming the namespace can change what it refers to.
How the fix works¶
The name is replaced with its fully qualified form, type arguments included (int stays int). using static and
aliases are checked too. An alias's own type stays a name (System.ValueTuple<System.IO.Stream, int>,
System.Nullable<...>, System.Int32): (.., ..), T? and int there need C# 12. Inside type arguments the
shorthand is kept, and so is the way a built-in type is written: System.ReadOnlyMemory<System.Char> stays (with
dotnet_style_predefined_type_* set to false, IDE0049 would report char, and dotnet format can't fix it in an
alias), and List<String> becomes System.Collections.Generic.List<System.String>, like StyleCop.
When usings are sorted (dotnet_sort_system_directives_first or dotnet_separate_import_directive_groups is set, so
dotnet format sorts them), the fix sorts them too, with the same organizer: the qualified name usually belongs
elsewhere, and dotnet format would otherwise move it only on its next run.
Not reported¶
- Usings outside a namespace, names starting with
global::or an alias, and a type of the namespace the directive is in (like StyleCop). - A type argument that starts with an alias (
using T2 = System.ValueTuple<Tasks.Task, int>;withusing Tasks = System.Threading.Tasks;outside): it's kept as written, like an alias at the start of the name. - A qualified name that an enclosing namespace would hide: inside
namespace Lib.Inner, with a namespaceLib.Inner.Libaround,Lib.Thingwould meanLib.Inner.Lib.Thing.
Compared with StyleCop¶
Same positions and output, except the hidden-name case above (StyleCop's fix then refers to the wrong namespace) and
a type argument that starts with an alias: StyleCop accepts using T1 = Tasks.Task; but reports
using T2 = System.ValueTuple<Tasks.Task, int>; (#3884, open).