최근에, 나는 문 Dictionaries
대신에 1-1 관계를 매핑하는 것을 선호하게되었습니다 Switch
. 쓰기가 조금 더 빠르고 정신적으로 처리하기가 더 쉽다는 것을 알게되었습니다. 불행히도 객체의 새 인스턴스에 매핑 할 때 다음과 같이 정의하고 싶지 않습니다.
var fooDict = new Dictionary<int, IBigObject>()
{
{ 0, new Foo() }, // Creates an instance of Foo
{ 1, new Bar() }, // Creates an instance of Bar
{ 2, new Baz() } // Creates an instance of Baz
}
var quux = fooDict[0]; // quux references Foo
그 구조가 주어지면 CPU 사이클과 3 개의 객체를 만드는 메모리를 낭비하고 생성자가 포함 할 수있는 것을 수행하고 그중 하나만 사용했습니다. 또한 fooDict[0]
이 경우 다른 객체를 매핑 하면 Foo
의도 한대로 새 인스턴스를 만드는 것이 아니라 동일한 것을 참조하게 됩니다. 해결책은 대신 람다를 사용하는 것입니다.
var fooDict = new Dictionary<int, Func<IBigObject>>()
{
{ 0, () => new Foo() }, // Returns a new instance of Foo when invoked
{ 1, () => new Bar() }, // Ditto Bar
{ 2, () => new Baz() } // Ditto Baz
}
var quux = fooDict[0](); // equivalent to saying 'var quux = new Foo();'
이것이 너무 혼란스러운 지점에 도달하고 있습니까? 결국에는 놓치기 쉽습니다 ()
. 아니면 함수 / 표현에 매핑하는 것이 일반적인 관례입니까? 대안은 스위치를 사용하는 것입니다.
IBigObject quux;
switch(someInt)
{
case 0: quux = new Foo(); break;
case 1: quux = new Bar(); break;
case 2: quux = new Baz(); break;
}
어떤 호출이 더 허용됩니까?
- 빠른 검색 및 더 적은 키워드 (대소 문자 구분)를위한 사전
- 스위치 : 코드에서 더 일반적으로 발견되며 간접적으로 Func <> 객체를 사용할 필요가 없습니다.
답변
이것은 팩토리 패턴 에 대한 흥미로운 설명 입니다 . 나는 사전과 람다 표현의 조합을 좋아합니다. 그 컨테이너를 새로운 방식으로 보았습니다.
람다가 아닌 접근 방식이 필요한 것을 제공하지 않는다는 의견에서 언급했듯이 CPU 사이클에 대한 귀하의 질문에 대한 우려를 무시하고 있습니다.
나는 두 가지 접근법 (스위치 대 사전 + 람다)이 좋을 것이라고 생각합니다. 유일한 제한은 사전을 사용하여 리턴 된 클래스를 생성하기 위해 수신 할 수있는 입력 유형을 제한한다는 것입니다.
switch 문을 사용하면 입력 매개 변수에 대한 유연성이 향상됩니다. 그러나 이것이 문제가된다면 메소드 내부에 Dictionary를 랩핑하고 같은 결과를 얻을 수 있습니다.
팀에 새로운 것이면 코드에 주석을 달고 진행 상황을 설명하십시오. 팀 코드 검토를 요청하고 수행 한 작업을 안내하고이를 인식하도록합니다. 그 외에는 괜찮아 보입니다.
답변
C # 4.0은 Lazy<T>
두 번째 솔루션과 비슷한 클래스를 제공 하지만 “지연된 초기화”를보다 명확하게 외칩니다.
var fooDict = new Dictionary<int, Lazy<IBigObject>>()
{
{ 0, new Lazy(() => new Foo()) }, // Returns a new instance of Foo when invoked
{ 1, new Lazy(() => new Bar()) }, // Ditto Bar
{ 2, new Lazy(() => new Baz()) } // Ditto Baz
}
답변
독창적으로 나는 가독성이 그들 사이에 같다고 생각합니다. 로 의존성 주입을 수행하는 것이 더 쉽습니다 Dictionary
.
를 사용할 때 키가 있는지 확인 Dictionary
해야하며 그렇지 않은 경우 폴백을 제공해야합니다.
switch
정적 코드 경로 및 Dictionary
동적 코드 경로 (항목을 추가하거나 제거 할 수 있는)에 대한 명령문을 선호합니다 . 컴파일러는와 함께 switch
할 수없는 정적 최적화를 수행 할 수 있습니다 Dictionary
.
흥미롭게도,이 Dictionary
패턴은 사람들 이 파이썬에서 가끔하는 일입니다 switch
. 파이썬에는 문장 이 없기 때문 입니다. 그렇지 않으면 그들은 if-else 체인을 사용합니다.
답변
일반적으로 어느 쪽도 선호하지 않습니다.
이것을 소비하는 것은 무엇이든 사용할 수 Func<int, IBigObject>
있습니다. 그런 다음 매핑 소스는 사전 또는 스위치 문이나 웹 서비스 호출 또는 파일 조회 등을 갖는 메소드 일 수 있습니다.
구현에 관해서는 사전이 ‘하드 코드 사전, 조회 키, 결과 반환’에서 ‘파일에서 사전로드, 조회 키, 결과 반환’으로보다 쉽게 리팩토링되기 때문에 사전을 선호합니다.