2011-12-14 22 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

を読んでいる私の例では単なる例として、あまりにも動作します@アダム・マラスと@のD-スタンレーは、これは、共分散の問題で、述べたように。したがって、可能な限り、インターフェイスを使用します。既存の明示的なキャスト限り

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>()); 

3行目は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[]>です。 2つの参照があり、1つはタイプDictionary<int, string[]>で、タイプはIDictionary<int, IEnumerable<string>>です。

このコードに従うとどうなりますか?私たちはあなたが意図するような方法でDictionary<int, string[]>をキャストすることができ、上記のスニペットは...成功し

をコンパイル...そして、実行時に爆破することを提供

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

なぜですか?List<string> a string[]ではないためです。

enumerableDictionaryAdd方法は、任意のIEnumerable<string>を受け入れるが、作成されたオブジェクト(Dictionary<int, string[]>)はのみstring[]を受け付け方法を有します。 Dictionary<Int32, string[]>ないIDictionary<int, IEnumerable<string>>が1にキャストすることができないある理由である

。このような

+0

あなたが爆破しないようにするためには本当ですが、以下を実行する必要があります – MethodMan

+0

私はこれが共変/ contra-varianceの問題であり、 。エラーメッセージはちょうど希望の一見を与えました:_タイプ 'type1'を暗黙的に 'type2'に変換できません。明示的な変換が存在します(キャストがありませんか?)。使用法は読み取り専用のシナリオであり、これはあまり問題ではありません。私は実際には全く動作しないことを期待していました。私は、IEnumerableを可能な限り配列に暗黙的にキャストしているのか、そうでない場合はIEnumerableやその他のトリックを使用して配列を作成したかどうか疑問に思いました。約エラーメッセージは何ですか? – WaffleSouffle

0

何かが、私は、カンマで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++; 
} 
関連する問題