Я организую проект библиотеки, и у меня есть класс центрального менеджера с именем Scenegraph
и целая куча других классов, которые живут в пространстве имен Scenegraph.
Мне бы очень хотелось, чтобы граф сцены MyLib.Scenegraph
и другие классы были MyLib.Scenegraph.*
, но, похоже, единственный способ сделать это - сделать все остальные классы внутренними классами Scenegraph
в файле Scenegraph.cs, а это слишком громоздко. .
Вместо этого я организовал его как Mylib.Scenegraph.Scenegraph
и MyLib.Scenegraph.*
, что и как работает, но я обнаружил, что Visual Studio при некоторых условиях путается в том, имею ли я в виду класс или пространство имен.
Есть ли хороший способ организовать этот пакет так, чтобы он был удобен для пользователей, не сбивая весь мой код в неразбериху, которую невозможно поддерживать?
источник
using Foo.Bar;
позжеBar b
это явно относится кBar
классу (или перечислению) внутри пространства именFoo.Bar
. Настоящая причина не делать этого заключается в том, что компилятор C # не может правильно его понять, что ужасно удивительно и прискорбно. Все остальное - совет нечеткого стиля.Присвоение того же имени пространству имен и классу может запутать компилятор, как говорили другие.
Как тогда это назвать?
Если пространство имен имеет несколько классов, найдите имя, которое определяет все эти классы.
Если пространство имен имеет только один класс (и отсюда искушение дать ему то же имя), назовите пространство имен ClassName NS . По крайней мере, так Microsoft называет свои пространства имен.
источник
Я бы посоветовал вам последовать совету, который я получил,
microsoft.public.dotnet.languages.csharp
чтобы использоватьMyLib.ScenegraphUtil.Scenegraph
иMyLib.ScenegraphUtil.*
.источник
CA1724: Type Names Should Not Match Namespaces
...По сути, если вы следуете анализу кода для правильного кодирования, это правило говорит, что не следует делать то, что вы пытаетесь сделать. Анализ кода очень полезен для поиска потенциальных проблем.
источник
Несмотря на то, что я согласен с другими ответами в том, что вы не должны называть свой класс так же, как свое пространство имен, бывают случаи, когда вы не можете соответствовать таким требованиям.
В моем случае, например, я не был человеком, принимающим такое решение, поэтому мне нужно было найти способ заставить его работать.
Итак, для тех, кто не может изменить имя пространства имен или имя класса, вот способ, которым вы можете заставить свой код работать.
// 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 }
В основном я создавал «псевдонимы» пространства имен, что позволило мне полностью определить класс, и «путаница» Visual Studio исчезла.
ПРИМЕЧАНИЕ. Вам следует избегать этого конфликта имен, если это в ваших силах. Вы должны использовать упомянутую технику только тогда, когда вы не контролируете рассматриваемые классы и пространства имен.
источник
Просто добавляю свои 2 цента:
У меня был следующий класс:
namespace Foo { public struct Bar { } public class Foo { //no method or member named "Bar" } }
Клиент был написан так:
using Foo; public class Blah { public void GetFoo( out Foo.Bar[] barArray ) { } }
Прощая ошибку, GetFoo не возвращает результат вместо использования параметра out, компилятор не смог разрешить тип данных Foo.Bar []. Он возвращал ошибку: не удалось найти тип или пространство имен Foo.Bar.
Похоже, что когда он пытается скомпилировать, он разрешает Foo как класс и не находит встроенный класс Bar в классе Foo. Также не удалось найти пространство имен Foo.Bar. Не удалось найти класс Bar в пространстве имен Foo. Точки в пространстве имен НЕ являются синтаксическими. Токеном является вся строка, а не слова, разделенные точками.
Такое поведение было продемонстрировано в VS 2015 с .Net 4.6.
источник
Как уже говорили другие, рекомендуется избегать именования класса так же, как его пространство имен.
Вот несколько дополнительных предложений по именованию из ответа svick на связанный вопрос «Тот же класс и имя пространства имен» в Software Engineering Stack Exchange:
(Обратите внимание , что ответ выше использование
Model.DataSource.DataSource
,Model.QueryStorage.QueryStorage.
иModel.Project.Project
в качестве примеров , а неMyLib.Scenegraph.Scenegraph
.)(Я также нашел полезными другие предложения по именованию в других ответах здесь.)
источник
Старый пост, но здесь я иду с другой идеей, которая может кому-то помочь:
«... но кажется, что единственный способ сделать это - сделать все остальные классы внутренними классами Scenegraph в файле Scenegraph.cs, а это слишком громоздко».
Это действительно лучшая реализация для множества сценариев. Но я согласен, что наличие всего этого кода в одном файле .cs раздражает (мягко говоря).
Вы можете решить эту проблему, сделав базовый класс «частичным классом», а затем продолжив создание внутренних классов в их собственных файлах (просто помните, что им нужно будет объявить дополнение базового класса, а затем перейти к конкретному внутреннему классу для этого файла).
Что-то типа...
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 } } }
Я действительно думаю, что это ближе к тому, чтобы вы могли получить чистую реализацию внутренних классов без необходимости загромождать все внутри одного огромного и беспорядочного файла.
источник
Это происходит, когда это основной класс пространства имен. Таким образом, это одна из мотиваций - поместить пространство имен в библиотеку, и проблема исчезнет, если вы добавите «Lib» к имени пространства имен ...
namespace SocketLib { class Socket {
источник