2011-12-14 2 views
2

코드를 작성하면 CS0266이 생성됩니다.명시 적 형 변환이 존재하지만 Dictionary <int, string []>에 대해 IDictionary <int, IEnumerable <string>>

Dictionary<Int32, string[]> d1 = new Dictionary<int, string[]>(); 
IDictionary<int, IEnumerable<string>> ide1 = d1; // CS0266 

명시 적 형변환이 있다는 힌트는 명시 적 형변환이 문제를 해결할 것을 제안합니다.

IDictionary<int, IEnumerable<string>> ide1 = (IDictionary<int, IEnumerable<string>>)d1; // No error, but throws an exception 

이 캐스트를 만드는 방법이 있습니까? string[][]IEnumerable<IEnumerable<string>>에서 작동합니까?

namespace Quickie 
{ 
    class QuickieArray 
    { 
     private static void TestCastDictionaryWithArrayValue() 
     { 
      Console.WriteLine(); 
      Console.WriteLine("===TestCastDictionaryWithArrayValue==="); 
      Dictionary<Int32, string[]> d1 = new Dictionary<int, string[]>(); 
      d1[1] = new string[]{"foo"}; 
      IDictionary<int, string[]> id1 = d1; 
      Console.WriteLine("id1 is null: {0}", id1 == null); 
      IDictionary<int, IEnumerable<string>> ide1 = id1 as IDictionary<int, IEnumerable<string>>; 
      IDictionary<int, IEnumerator<string>> iden1 = id1 as IDictionary<int, IEnumerator<string>>; 
      Console.WriteLine("ide1 is null: {0}", ide1 == null); 
      Console.WriteLine("iden1 is null: {0}", iden1 == null); 

      Console.WriteLine(); 
     } 
     internal static void Test() 
     { 
      Console.WriteLine(); 
      Console.WriteLine("=QuickieArray="); 
      TestCastDictionaryWithArrayValue(); 
     } 
    } 
} 

출력 :

=== TestCastDictionaryWithArrayValue ===
ID1가 null : 거짓
IDE1가 null : 참
iden1가 null : 참

+0

주의 :'System.Int32'와'int'는 같은 타입입니다; C#에서는 후자가 전자의 별칭입니다. (물론'id1'는 'null'이 아닙니다.) – dlev

+0

명시 적 캐스트의 적법성에 대한 좀 더 자세한 정보는 다른 질문에 대한 최근 답변을 참조하십시오. http://stackoverflow.com/a/8402861/55943 – mquander

답변

1

에서 읽고 있습니다 내 예제에서 예제로도 작동합니다. 따라서 가능하면 인터페이스를 사용하십시오. 기존의 명시 적 캐스트로까지

using System; 
using System.Collections.Generic; 

namespace Quickie 
{ 
    class QuickieArray 
    { 
     private static void TestCastIDictionaryWithArrayValue() 
     { 
      Console.WriteLine(); 
      Console.WriteLine("===TestCastIDictionaryWithArrayValue==="); 
      IDictionary<int, IEnumerable<string>> d1 = new Dictionary<int, IEnumerable<string>>(); 
      d1[1] = new string[] { "foo" }; 
      IDictionary<int, IEnumerable<string>> id1 = d1; 
      Console.WriteLine("id1 is null: {0}", id1 == null); 
      IDictionary<int, IEnumerable<string>> ide1 = id1 as IDictionary<int, IEnumerable<string>>; 
      IDictionary<int, IEnumerator<string>> iden1 = id1 as IDictionary<int, IEnumerator<string>>; 
      Console.WriteLine("ide1 is null: {0}", ide1 == null); 
      Console.WriteLine("iden1 is null: {0}", iden1 == null); 

      Console.WriteLine(); 
     } 

     internal static void Test() 
     { 
      Console.WriteLine(); 
      TestCastIDictionaryWithArrayValue(); 
     } 
    } 
} 

그리고 예를 들어,보다 파생 형으로 인스턴스 데이터를 보유 덜 파생 유형으로 IDictionary<Int32, IEnumerable<string>>을 사용할 수 있습니까? 아닙니다.

6

없음 던지기도, 거기 있어야한다. 다음과 같은 상상 :

 Dictionary<Int32, string[]> d1 = new Dictionary<int, string[]>(); 
     IDictionary<int, IEnumerable<string>> ide1 = d1; 
     ide1.Add(99,new List<string>()); 

을 세 번째 줄은 IDictionary<int, IEnumerable<string>>에 완벽하게 허용하지만, 그것은 IDictionary<int, string[]> 허용하지 않습니다.

7

이것은 고전적인 공분산/반란 문제입니다. Dictionary<Int32, string[]>이 아니고이 아니고 IDictionary<int, IEnumerable<string>>이 아니고 으로 표시 될 수없는 이유를 증명하는 간단한 예제를 보여 드리겠습니다.

의 질문 작품의 출연진과이 코드는 컴파일 잠시 척하자

Dictionary<int, string[]> arrayDictionary = new Dictionary<int, string[]>(); 
IDictionary<int, IEnumerable<string>> enumerableDictionary = arrayDictionary; 

지금, 우리는 하나의 개체가 있습니다. 분명히 유형이 Dictionary<int, string[]>입니다. 여기에는 두 가지 참조가 있는데 하나는 Dictionary<int, string[]> 유형이고 다른 하나는 IDictionary<int, IEnumerable<string>> 유형 중 하나입니다.

이 코드가 따른다면 어떻게됩니까?

List<string> stringList = new List<string>(); 
enumerableDictionary.Add(0, stringList); 

우리는 당신이하고자하는 것입니다 방법으로 Dictionary<int, string[]> 캐스팅 수 있다는 다만, 위의 조각은 ... 성공적으로

를 컴파일 할 것입니다 ... 그리고 런타임에 날려. 왜?List<string> a string[]이 아니기 때문입니다.

enumerableDictionaryAdd

방법은 IEnumerable<string>을 허용하지만, 작성된 실제 객체 ( Dictionary<int, string[]>)은 만이 string[]을받는 방법이있다. Dictionary<Int32, string[]> 인 이유입니다

IDictionary<int, IEnumerable<string>> 하나에 캐스트 할 수 없습니다.이 같은

+0

그것은 당신이 다음을 할 필요가있을 것입니다 폭파하지 않기 위해 사실입니다 – MethodMan

+0

이것은 공동/contra - variance 문제이며, 게으른 말하는 것은 아닙니다 . 오류 메시지는 단지 희망의 희미한 빛을주었습니다 : _ 암시 적으로 'type1'유형을 'type2'로 변환 할 수 없습니다. 명시 적 변환이 존재합니다 (캐스트가 누락 되었습니까?) _. 사용은 읽기 문제가 아닌 읽기 전용 시나리오입니다. 나는 실제로 그것이 전혀 작동하지 않을 것으로 예상했다. 이 메시지는 암묵적으로 IEnumerable을 가능하면 배열로 다시 캐스팅했는지 또는 IEnumerable 또는 다른 트릭을 사용하여 배열을 만들었는지 궁금하게 만들었습니다 (아무도 좋은 아이디어는 아닐 것입니다). 오류 메시지가 무엇에 관한거야? – WaffleSouffle

0

뭔가 그냥 @ 아담 - 마라와 D-스탠리가 언급 @, 이것은 공분산 문제이기 때문에 쉼표 DELIM 필드

var intFileCount = 0; 
Dictionary<int, string[]> dctListRecords = null; 
//initialize a capacity if you want 
dctListRecords = new Dictionary<int, string[]>(strLinesStockRecord.Count()); 
foreach (string strLineSplit in strLinesStockRecord) 
{ 
    lstSplitList2 = strLineSplit.Split(chrCOMMA_SEP).ToList(); 
    dctListRecords.Add(intFileCount, lstSplitList2.ToArray()); 
    //this allows you to use the string value inside of string[] 
    lstSplitList2.Clear(); 
    intFileCount++; 
} 
관련 문제