[c#] 이름이 같은 네임 스페이스와 클래스?

저는 라이브러리 프로젝트를 구성하고 있으며 중앙 관리자 클래스라는 이름 Scenegraph과 Scenegraph 네임 스페이스에있는 다른 클래스가 있습니다.

내가 정말로 원하는 것은 장면 그래프가 MyLib.Scenegraph되고 다른 클래스가되는 것입니다 MyLib.Scenegraph.*.하지만 그렇게하는 유일한 방법은 다른 모든 클래스를 ScenegraphScenegraph.cs 파일 의 내부 클래스로 만드는 것입니다. 너무 다루기 어렵습니다. .

대신, 나는 그것을 Mylib.Scenegraph.Scenegraphand 로 구성했는데 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.ScenegraphMyLib.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
        }
    }
}

나는 이것이 하나의 거대하고 지저분한 파일 안에 모든 것을 어지럽히 지 않고도 내부 클래스를 깔끔하게 구현할 수있는 것에 더 가깝다고 생각합니다.