List.AsReadOnly()
이 IReadOnlyCollection
대신 ReadOnlyCollection
을 반환한다는 사실이 나에게 어려움을 겪었습니다. 반환 된 컬렉션은 이 Dictionary
이므로 IReadOnlyCollection
으로 자동 업데이트 될 수 없습니다. 이것은 이상하게 보였고 .Net 소스 코드를 검토 한 결과 메서드는 List
에 대해 Dictionary
에 대해 수행하는 것, 즉 인터페이스 대신 구체적인 클래스를 반환하는 작업과 다르다는 것을 확인했습니다.List.AsReadOnly가 ReadOnlyCollection을 반환하지만 Dictionary.AsReadOnly가 IReadOnlyDictionary를 반환하는 이유는 무엇입니까?
이유가 누구인지 설명 할 수 있습니까? 특히 우리가 가능할 때, 특히 공개 할 때 인터페이스를 사용하기를 원하기 때문에 이러한 불일치가 발생하는 것은 당연한 것입니다.
제 코드에서는 소비자가 개인적인 방법 이었기 때문에 IReadOnlyDictionary<T, IReadOnlyCollection<T>>
에서 IReadOnlyDictionary<T, ReadOnlyCollection<T>>
으로 매개 변수 서명을 변경할 수 있다고 생각했습니다. 그러나, 나는이이 컬렉션 값을 수정할 수있는 개인 방법처럼 보이게 것을 깨달았다, 그래서 제대로 인터페이스를 사용하기 위해 이전의 코드로 성가신 명시 적 캐스트를 넣어 : 이후
.ToDictionary(
item => item,
item => (IReadOnlyCollection<T>) relatedItemsSelector(item)
.ToList()
.AsReadOnly() // Didn't expect to need the direct cast
)
아, 그리고 나는 항상 공분산과 반동을 혼란스럽게하고 있습니다. 누군가 자동 캐스팅을 방해하는 것을 말해 주시겠습니까? 그리고 미래를 생각해내는 방법을 생각 나게 해 주시겠습니까? (예 : 콜렉션은 ______ [input/output] 매개 변수에 대해 ______variant [공동/contra]가 아닙니다.) 인터페이스의 많은 구현이있을 수 있고 모든 요청 된 유형에 대한 사전의 개별 요소 내가이 단순한면조차도 불지 않는 한 은을 이해하지 못한다.이 경우에는 내가 올바른 설정을 도울 수 있기를 바랍니다.
오 오 오! 나는 그것이 자동적으로 캐스팅되지 않을 것이라고 가정하고있었습니다. * covariant가 아니었지만, 이제는 IReadOnlyCollection이 읽기 전용이기 때문에 컴파일러는 파생 된 타입에서베이스로 캐스팅하는 것이 안전하다는 것을 알 수 있습니다. . 그렇다면 왜 내가 명시 적 캐스트를해야만 했습니까? – ErikE
공분산과 반공립은 두 개의 일반 * 인터페이스 * 사이에서 캐스팅하고 * 유형 매개 변수 * (기본에서 파생 또는 그 반대로 변경)에서만 발생합니다. 당신이 사용한 캐스트는 캐스트 일뿐입니다.'ReadOnlyCollection'는'IReadOnlyList '를 구현했기 때문에 허용되었습니다. –
아, 그럴리가. 점점 더 명확 해지고 있습니다. 왜 암묵적으로 던지지 못했을까요? – ErikE