Zgodnie z dokumentacją StyleCop:
SA1200: UsingDirectivesMustBePlacedWithinNamespace
Przyczyna AC # za pomocą dyrektywy jest umieszczony poza elementem przestrzeni nazw.
Opis reguły Naruszenie tej reguły występuje, gdy dyrektywa using lub dyrektywa using-alias zostanie umieszczona poza elementem przestrzeni nazw, chyba że plik nie zawiera żadnych elementów przestrzeni nazw.
Na przykład poniższy kod spowodowałby dwa naruszenia tej reguły.
using System;
using Guid = System.Guid;
namespace Microsoft.Sample
{
public class Program
{
}
}
Poniższy kod nie spowoduje jednak naruszenia tej reguły:
namespace Microsoft.Sample
{
using System;
using Guid = System.Guid;
public class Program
{
}
}
Ten kod skompiluje się czysto, bez żadnych błędów kompilatora. Nie jest jednak jasne, która wersja typu Guid jest przydzielana. Jeśli dyrektywa using zostanie przeniesiona do przestrzeni nazw, jak pokazano poniżej, wystąpi błąd kompilatora:
namespace Microsoft.Sample
{
using Guid = System.Guid;
public class Guid
{
public Guid(string s)
{
}
}
public class Program
{
public static void Main(string[] args)
{
Guid g = new Guid("hello");
}
}
}
Kod kończy się niepowodzeniem w przypadku następującego błędu kompilatora, znalezionego w wierszu zawierającym Guid g = new Guid("hello");
CS0576: Przestrzeń nazw „Microsoft.Sample” zawiera definicję sprzeczną z aliasem „Guid”
Kod tworzy alias typu System.Guid o nazwie Guid, a także tworzy własny typ o nazwie Guid z pasującym interfejsem konstruktora. Później kod tworzy instancję typu Guid. Aby utworzyć to wystąpienie, kompilator musi wybrać jedną z dwóch różnych definicji Guid. Kiedy dyrektywa using-alias zostanie umieszczona poza elementem przestrzeni nazw, kompilator wybierze lokalną definicję Guid zdefiniowaną w lokalnej przestrzeni nazw i całkowicie zignoruje dyrektywę using-alias zdefiniowaną poza przestrzenią nazw. To niestety nie jest oczywiste podczas czytania kodu.
Gdy dyrektywa using-alias znajduje się w obszarze nazw, kompilator musi jednak wybierać między dwoma różnymi, sprzecznymi typami Guid, które są zdefiniowane w tej samej przestrzeni nazw. Oba te typy zapewniają zgodnego konstruktora. Kompilator nie może podjąć decyzji, więc oznacza błąd kompilatora.
Umieszczenie dyrektywy using-alias poza przestrzenią nazw jest złą praktyką, ponieważ może prowadzić do nieporozumień w sytuacjach takich jak ta, gdzie nie jest oczywiste, która wersja tego typu jest faktycznie używana. Może to potencjalnie prowadzić do błędu, który może być trudny do zdiagnozowania.
Umieszczenie dyrektyw przy użyciu aliasu w elemencie przestrzeni nazw eliminuje to jako źródło błędów.
- Wiele przestrzeni nazw
Umieszczanie wielu elementów przestrzeni nazw w jednym pliku jest na ogół złym pomysłem, ale jeśli i kiedy to zostanie zrobione, dobrym pomysłem jest umieszczenie wszystkich za pomocą dyrektyw w obrębie każdego z elementów przestrzeni nazw, a nie globalnie na górze pliku. Spowoduje to ścisłe zawężenie przestrzeni nazw, a także pomoże uniknąć opisanych powyżej zachowań.
Należy zauważyć, że kiedy kod został napisany przy użyciu dyrektyw umieszczonych poza przestrzenią nazw, należy zachować ostrożność podczas przenoszenia tych dyrektyw w przestrzeni nazw, aby upewnić się, że nie zmienia to semantyki kodu. Jak wyjaśniono powyżej, umieszczenie dyrektyw przy użyciu aliasu w elemencie przestrzeni nazw umożliwia kompilatorowi wybór między konfliktami typów w sposób, który nie nastąpi, gdy dyrektywy zostaną umieszczone poza przestrzenią nazw.
Jak naprawić naruszenia Aby naprawić naruszenie tej reguły, przenieś wszystkie za pomocą dyrektyw i dyrektyw przy użyciu aliasu w elemencie przestrzeni nazw.