Organizuję projekt biblioteki i mam nazwaną centralną klasę menedżera Scenegraph
oraz całą masę innych klas, które żyją w przestrzeni nazw Scenegraph.
Naprawdę chciałbym, żeby scenegraph był, MyLib.Scenegraph
a inne klasy były MyLib.Scenegraph.*
, ale wydaje się, że jedynym sposobem na to byłoby uczynienie wszystkich innych klas wewnętrznymi Scenegraph
w pliku Scenegraph.cs, a to jest po prostu zbyt nieporęczne .
Zamiast tego zorganizowałem to jako Mylib.Scenegraph.Scenegraph
i MyLib.Scenegraph.*
, który rodzaj działa, ale uważam, że Visual Studio jest zdezorientowany w pewnych warunkach, czy mam na myśli klasę, czy przestrzeń nazw.
Czy istnieje dobry sposób na zorganizowanie tego pakietu, tak aby był wygodny dla użytkowników, bez konieczności umieszczania całego kodu razem w niemożliwym do utrzymania bałaganie?
źródło
using Foo.Bar;
PóźniejBar b
dość wyraźnie odnosi się doBar
klasy (lub wyliczenia) wewnątrz przestrzeni nazwFoo.Bar
. Prawdziwym powodem, aby tego nie robić, jest po prostu to, że kompilator C # nie potrafi tego poprawnie zrozumieć, co jest strasznie zaskakujące i niefortunne. Wszystko inne to porady dotyczące wełnianego stylu.Nadanie tej samej nazwy przestrzeni nazw i klasie może zmylić kompilator, jak powiedzieli inni.
Jak więc to nazwać?
Jeśli przestrzeń nazw ma wiele klas, znajdź nazwę, która definiuje wszystkie te klasy.
Jeśli przestrzeń nazw ma tylko jedną klasę (i stąd pokusa nadania jej tej samej nazwy), nazwij ją ClassName NS . Tak przynajmniej Microsoft nazywa swoje przestrzenie nazw.
źródło
Proponuję, aby postępować zgodnie z zaleceniami wsiadłem
microsoft.public.dotnet.languages.csharp
do użytkuMyLib.ScenegraphUtil.Scenegraph
iMyLib.ScenegraphUtil.*
.źródło
CA1724: Type Names Should Not Match Namespaces
...Zasadniczo, jeśli zastosujesz się do analizy kodu w celu prawidłowego kodowania, ta reguła mówi, aby nie robić tego, co próbujesz zrobić. Analiza kodu jest bardzo przydatna, pomagając znaleźć potencjalne problemy.
źródło
Dodam tylko moje 2 centy:
Miałem następujące zajęcia:
namespace Foo { public struct Bar { } public class Foo { //no method or member named "Bar" } }
Klient został napisany w ten sposób:
using Foo; public class Blah { public void GetFoo( out Foo.Bar[] barArray ) { } }
Wybaczając błąd, że GetFoo nie zwraca danych wyjściowych zamiast użyć parametru out, kompilator nie mógł rozpoznać typu danych Foo.Bar []. Zwracał błąd: nie można znaleźć typu lub przestrzeni nazw Foo.Bar.
Wygląda na to, że przy próbie kompilacji rozwiązał Foo jako klasę i nie znalazł osadzonej klasy Bar w klasie Foo. Nie mógł również znaleźć przestrzeni nazw o nazwie Foo.Bar. Nie udało się wyszukać klasy Bar w przestrzeni nazw Foo. Kropki w przestrzeni nazw NIE są syntaktyczne. Cały ciąg jest tokenem, a nie słowami rozdzielonymi kropkami.
To zachowanie było widoczne w VS 2015 z .Net 4.6
źródło
Chociaż zgadzam się z innymi odpowiedziami, mówiąc, że nie powinieneś nazywać swojej klasy tak samo, jak przestrzeń nazw , są chwile, w których nie możesz spełnić takich wymagań.
Na przykład w moim przypadku to nie ja podejmowałem taką decyzję, dlatego musiałem znaleźć sposób, żeby to zadziałało.
Więc dla tych, którzy nie mogą zmienić nazwy przestrzeni nazw ani nazwy klasy, jest tutaj sposób, w jaki możesz sprawić, by kod działał.
// Foo.DLL: namespace Foo { public class Foo { } } // Bar.DLL: namespace Bar { public class Foo { } } // Blah.DLL: namespace Blah { using FooNSAlias = Foo;//alias using BarNSAlias = Bar;//alias class C { FooNSAlias.Foo foo; }//use alias to fully qualify class name }
Zasadniczo utworzyłem „aliasy” przestrzeni nazw, co pozwoliło mi w pełni zakwalifikować klasę, a „zamieszanie” w Visual Studio zniknęło.
UWAGA: Powinieneś unikać tego konfliktu nazw, jeśli masz nad tym kontrolę. Powinieneś używać wspomnianej techniki tylko wtedy, gdy nie masz kontroli nad przedmiotowymi klasami i przestrzeniami nazw.
źródło
Jak powiedzieli inni, dobrą praktyką jest unikanie nazywania klasy tak samo, jak jej przestrzeń nazw.
Oto kilka dodatkowych sugestii dotyczących nazewnictwa z odpowiedzi użytkownika svick na pytanie pokrewne „Ta sama klasa i nazwa przestrzeni nazw” na giełdzie Software Engineering Stack Exchange:
(Należy pamiętać, że powyższych zastosowań odpowiedź
Model.DataSource.DataSource
,Model.QueryStorage.QueryStorage.
iModel.Project.Project
jako przykłady zamiastMyLib.Scenegraph.Scenegraph
).(Przydały mi się również inne sugestie dotyczące nazewnictwa w innych odpowiedziach).
źródło
Stary post, ale oto inny pomysł, który może komuś pomóc:
„… ale wydaje się, że jedynym sposobem na to byłoby uczynienie wszystkich innych klas wewnętrznymi klasami Scenegraph w pliku Scenegraph.cs, a to jest po prostu zbyt nieporęczne”.
To naprawdę lepsza implementacja dla wielu scenariuszy. Ale zgadzam się, że posiadanie całego tego kodu w tym samym pliku .cs jest denerwujące (delikatnie mówiąc).
Możesz to rozwiązać, zmieniając klasę bazową jako „klasę częściową”, a następnie kontynuować tworzenie klas wewnętrznych w swoich własnych plikach (pamiętaj tylko, że będą one musiały zadeklarować uzupełnienie klasy bazowej a następnie kontynuować z określoną klasą wewnętrzną dla tego pliku).
Coś jak...
Scenegraph.cs:
namespace MyLib { public partial class Scenegraph { //Scenegraph specific implementations } }
DependentClass.cs:
namespace MyLib { public partial class Scenegraph { public class DependentClass { //DependentClass specific implementations } } }
Myślę, że jest to tym bliższe do uzyskania czystej implementacji klas wewnętrznych, bez konieczności zaśmiecania wszystkiego w jednym ogromnym i niechlujnym pliku.
źródło
Dzieje się tak, gdy jest to główna klasa przestrzeni nazw. Więc jedną z motywacji jest umieszczenie przestrzeni nazw w bibliotece, a problem zniknie, jeśli dodasz „Lib” do nazwy przestrzeni nazw ...
namespace SocketLib { class Socket {
źródło