[c#] 이름이 같은 네임 스페이스와 클래스?
저는 라이브러리 프로젝트를 구성하고 있으며 중앙 관리자 클래스라는 이름 Scenegraph
과 Scenegraph 네임 스페이스에있는 다른 클래스가 있습니다.
내가 정말로 원하는 것은 장면 그래프가 MyLib.Scenegraph
되고 다른 클래스가되는 것입니다 MyLib.Scenegraph.*
.하지만 그렇게하는 유일한 방법은 다른 모든 클래스를 Scenegraph
Scenegraph.cs 파일 의 내부 클래스로 만드는 것입니다. 너무 다루기 어렵습니다. .
대신, 나는 그것을 Mylib.Scenegraph.Scenegraph
and 로 구성했는데 MyLib.Scenegraph.*
, 어떤 종류의 작동하지만 Visual Studio가 클래스 또는 네임 스페이스를 참조하는지 여부에 대해 일부 조건에서 혼란스러워합니다.
이 패키지를 구성하는 좋은 방법이있어 유지 관리 할 수없는 엉망으로 내 모든 코드를한데 모으지 않고 사용자가 편리하게 사용할 수 있습니까?
답변
나는 그것의 네임 스페이스와 같은 참조 클래스 이름을 권장하지 않습니다 이 .
프레임 워크 디자인 지침은 섹션 3.4에 “네임 스페이스와 해당 네임 스페이스의 유형에 동일한 이름을 사용하지 마십시오”라고 말합니다. 그건:
namespace MyContainers.List
{
public class List { … }
}
왜 이것이 나쁜가요? 오, 방법을 세어 보겠습니다.
한 가지를 언급하고 있다고 생각하지만 실제로는 다른 것을 언급하는 상황에 처할 수 있습니다. 이 불행한 상황에 처했다고 가정 해 보겠습니다. Blah.DLL을 작성하고 Foo.DLL 및 Bar.DLL을 가져 오는 중입니다. 불행히도 둘 다 Foo라는 유형이 있습니다.
// Foo.DLL:
namespace Foo { public class Foo { } }
// Bar.DLL:
namespace Bar { public class Foo { } }
// Blah.DLL:
namespace Blah
{
using Foo;
using Bar;
class C { Foo foo; }
}
컴파일러에서 오류가 발생합니다. “Foo”는 Foo.Foo와 Bar.Foo 사이에서 모호합니다. Bummer. 이름을 완전히 정규화하여 수정하겠습니다.
class C { Foo.Foo foo; }
이제 ” Foo.Foo의 Foo는 Foo.Foo와 Bar.Foo간에 모호합니다 “라는 모호성 오류가 발생 합니다. 우리는 여전히 첫 번째 Foo가 무엇을 의미하는지 알지 못합니다. 그리고 우리가 그것을 알아낼 때까지 우리는 두 번째 Foo가 무엇을 의미하는지 알아 내려고 노력조차하지 않습니다.
답변
네임 스페이스와 클래스에 동일한 이름을 지정하면 다른 사람들이 말한 것처럼 컴파일러를 혼동 할 수 있습니다.
그럼 어떻게 이름을 지 을까요?
네임 스페이스에 여러 클래스가있는 경우 모든 클래스를 정의하는 이름을 찾으십시오.
네임 스페이스에 클래스가 하나만 있는 경우 (따라서 동일한 이름을 지정하려는 유혹) 네임 스페이스 ClassName NS . 이것은 Microsoft가 최소한 네임 스페이스의 이름을 지정하는 방법입니다.
답변
난 당신이 내가에있어 조언을 따를 것을 제안 microsoft.public.dotnet.languages.csharp
사용에 MyLib.ScenegraphUtil.Scenegraph
와 MyLib.ScenegraphUtil.*
.
답변
CA1724: Type Names Should Not Match Namespaces
…
기본적으로 올바른 코딩을 위해 Code Analysis를 따르는 경우이 규칙은 수행하려는 작업을하지 말라고 말합니다. 코드 분석은 잠재적 인 문제 를 찾는 데 매우 유용 합니다.
답변
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 ) {
}
}
out 매개 변수를 사용하는 대신 출력을 반환하지 않는 GetFoo 오류를 용서하면 컴파일러는 Foo.Bar [] 데이터 유형을 확인할 수 없습니다. 오류를 반환했습니다 : 유형 또는 네임 스페이스를 찾을 수 없습니다 Foo.Bar.
컴파일을 시도 할 때 Foo를 클래스로 확인하고 Foo 클래스에서 포함 된 클래스 Bar를 찾지 못한 것으로 보입니다. 또한 Foo.Bar라는 네임 스페이스를 찾을 수 없습니다. Foo 네임 스페이스에서 Bar 클래스를 찾지 못했습니다. 이름 공간의 점은 구문이 아닙니다. 전체 문자열은 점으로 구분 된 단어가 아니라 토큰입니다.
이 동작은 .Net 4.6을 실행하는 VS 2015에서 나타났습니다.
답변
클래스 이름을 네임 스페이스와 동일하게 지정해서는 안된다는 다른 답변에 동의하지만 이러한 요구 사항을 준수 할 수없는 경우가 있습니다.
예를 들어 제 경우에는 그러한 결정을 내리는 사람이 아니었기 때문에 그 결정을 내리는 방법을 찾아야했습니다.
따라서 네임 스페이스 이름이나 클래스 이름을 변경할 수없는 사람들을 위해 여기에서 코드를 작동시킬 수있는 방법이 있습니다.
// 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 “혼란”이 사라졌습니다.
참고 :
제어 할 수있는 경우이 명명 충돌을 피해야합니다. 문제의 클래스와 네임 스페이스를 제어 할 수 없을 때만 언급 된 기술을 사용해야합니다.
답변
이전 게시물이지만 여기에 누군가에게 도움이 될 수있는 다른 아이디어가 있습니다.
“…하지만 그렇게하는 유일한 방법은 Scenegraph.cs 파일에서 Scenegraph의 다른 모든 클래스 내부 클래스를 만드는 것입니다. 너무 다루기 어렵습니다.”
이것은 많은 시나리오에서 실제로 더 나은 구현입니다. 그러나 동일한 .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
}
}
}
나는 이것이 하나의 거대하고 지저분한 파일 안에 모든 것을 어지럽히 지 않고도 내부 클래스를 깔끔하게 구현할 수있는 것에 더 가깝다고 생각합니다.