2009-06-30 4 views
0

는 내가 가진 :IDictionary, 사전

IDictionary<string, IDictionary<string, IList<long>>> OldDic1; 

(단지 설명을 위해, 그것은 인스턴스화 값을 가지고있다 - 다른 곳)

가 왜이 작업을 수행 할 수 있습니다 :

Dictionary<string, IDictionary<string, IList<long>>> dic1 = 
    OldDic1 as Dictionary<string, IDictionary<string, IList<long>>>; 

기본적으로이 줄을 실행 한 후 dic1은 OldDic1의 모든 값을가집니다. 공장.

그러나 나는이 작업을 수행 할 때

Dictionary<string, Dictionary<string, List<long>>> dic1 = 
    OldDic1 as Dictionary<string, Dictionary<string, List<long>>>; 

내가 널 얻을, 그것은 충돌하지 않는 그것을 제외 캐스팅과 동일하며 대신이 null를 돌려줍니다. 그래서 문제가 인터페이스에서 유형으로 변환 할 수없는 이유는 무엇입니까? 거기에 해결책이 있습니까? 그리고 다른 방법으로 그것이 처음에 저장되는 방식을 바꾸는 것입니까?

+0

캐스팅은 다소 혼란 스럽습니다. 이런 종류의 캐스트를 수행 할 때 (또는 "as"를 사용하는 경우) 기본적으로 저장소에서 객체가 실제로 지정된 유형인지 여부 만 확인하면됩니다. 그 유형을 가진 새로운 객체를 만들지 않고 있습니다. 그냥 확인하는 것입니다. 확실하지 않은 경우 http://blogs.msdn.com/ericlippert/archive/2009/03/19/representation-and-identity.aspx –

+0

감사합니다. 훌륭한 기사입니다. – ra170

답변

2

일반 매개 변수가 아닌 가장 바깥 쪽 인터페이스/클래스 이름 만 다시 캐스팅 할 수 있습니다. 두 번째 캐스트가 작동하지 않는 이유는 "포함 된"객체를 캐스팅 할 수있는 경우에도 한 배열 유형에서 다른 배열 유형으로 캐스트 할 수없는 것과 같은 이유입니다. 이유는 다음과 같습니다.

List<object> objects; 
List<string> strings; 

objects = strings as List<object>; 
// Uh oh, that's not a string! 
objects.Add(42); 

objects = new List<object> { "The", "answer", "is", 42 }; 
// Uh oh, now strings contains an integer? 
strings = objects as List<string>; 

두 번째 경우에도 같은 결과가 발생합니다. 실제로는 Dictionary이 아니며 을 OldDic1에 추가 한 다음 dic1이 폭발 할 수 있습니다. 비 Dictionary 값을 갖습니다. Ruh! 당신은 용기가있을 때 X는 각 동일 같이

그래서, 당신은 오랫동안 다시 IList<X>에서 List<X>로 변경 할 수 있습니다.

+0

배열 요소 형식이 다른 경우 C#에서 다른 배열 형식으로 캐스팅 할 수 있다는 것을 제외하면 캐스트 할 수있는 참조 유형입니다. 요소 유형이 참조 유형 인 경우 C#에서는 배열 변환이 공변입니다. 이런 종류의 공분산은 실제로 타입을 안전하게하지 않습니다! 이것이 형식 시스템에 추가 된 것은 불행한 일입니다. –

0

이 동작은 C#의 as keyword과 관련됩니다. 사전은 IDictionary와 같은 것이 아닙니다.

다른 방법으로 캐스팅 한 경우 covariance and contravariance에 대한 지원이 증가 된 다음 버전의 .NET에서 작동하도록 할 수 있습니다.

해결 방법 을 구체 사전/목록에 캐스팅해야하는 경우 해결 방법이 필요할 경우 해당 유형의 저장소를 변경하십시오.

+0

구체적인 유형으로 형변환해야하는 이유는 유형이 필요한 DataContractJsonSerializer 때문입니다. 개체가 콘크리트 형식 인 경우 dic1.GetType()이라고 말할 수 있지만 인터페이스에서이 작업을 수행하면 DataContractJsonSeralizer .writeobject가 예외를 throw합니다. – ra170

관련 문제