2017-01-22 7 views
2

をゼロにします私は、リストから辞書を作成したいと思いますので、私はこの方法を使用します。辞書キー

Dictionary<long, List<MyType>> miDicIdMyType = myList.GroupBy(x => x.ForeignKey) 
               .ToDictionary(x => x.Key, x => x.ToList()); 

問題は時々プロパティがnullになることができるということですので、私はので、辞書を作成することができます辞書はヌル値をキーとして許可しません。

しかし、この特定のケースでは、このプロパティがnullであるかどうかをチェックしなければならず、nullの場合はエラーですので例外をスローします。この特定のメソッドでは、リスト内のすべての項目がこのプロパティにnullを持たないことを期待しています。

だから私はこれを行うことができます:

Dictionary<long, List<MyType>> miDicIdMyType = myList.GroupBy(x => (long)x.ForeignKey) 
             .ToDictionary(x => x.Key, x => x.ToList()); 

はそれは長いへのキャストですが、それがnullの場合、私はエラーを取得します。だから、基本的に私はこれをやってみたかった:

Dictionary<long, MyType> myDic = new Dictionary<long, myType>(); 
foreach (Mytype iterator in miList) 
{ 
    if (iterator.ForeignKey == null) 
    { 
     throw new ArgumentNullException("Some items in the collection has null value and it is not expected."); 
    } 

    if (myDic.ContainsKey(iterator.ForeignKey) == false) 
    { 
     myDic.Add(iterator.ForeignKey, new List<MyType>()); 
    } 

    myDic[iterator.ForeignKey].Add(iterator); 
} 

私はこれは良いコードであるかどうかを知りたいのか、私はLINQやラムダ式またはその他の方法で、より良い方法でそれを行うことができます。つまり、私のコードを簡素化します。

+0

あなたは複数行のラムダexpession 'のFunc 'に 'X => x.ForeignKey'をリファクタリングし、場合に例外をスローすることができます' T.ForeignKey'は* * NULLです。 – user3185569

+0

別のオプションは 'Dictionary >'です。 –

答えて

3

あなたはそのようなものをお探しですか?

Dictionary<long, List<MyType>> miDicIdMyType = myList.GroupBy(x => 
{ 
    if (x.ForeignKey == null) 
     throw new Exception(); 
    return x.ForeignKey.Value; 
}) 
.ToDictionary(x => x.Key, x => x.ToList()); 
+0

ありがとう、そうですね、このような文法について私があまり知らない瞬間を考えていました。 –

2

まず、ルックアップを作成しています。

var lookup = data.ToLookup(x => x.ForeignKey); 

キーをさらにチェックする必要がある場合、名前付きメソッドは再利用性と可読性が不思議です。

T IsNotNull<T>(T? obj, [CallerMemberName] string name = default(string)) where T : struct 
{ 
    if (obj == null) 
     throw new ArgumentNullException(name); 
    return obj.Value; 
} 

var lookup = data.ToLookup(x => IsNotNull(x.ForeignKey)); 

しかし、私はこれをまったく使用しないように注意します。あなたのlinqクエリは、特にレイジー評価では、副作用に頼ってはならない/引き起こすべきではありません。あなたは例外的な事件を起こすことを避けて、すべての費用を負担しなければなりません。この特定のケースでは、コードのこの時点での例外は不適切です。これはフィルタリングする必要のある単純なデータ問題です。

最初はフィルタリングしないのはなぜですか?

var lookup = data.Where(x => x.ForeignKey != null).ToLookup(x => x.ForeignKey.Value); 
+0

私はあなたのように最初の瞬間にフィルタリングすると思ったが、私はこの必要があることを推測するコレクションを2回、フィルタと他の辞書/ルックアップを作成する。 とにかく、私は例外をスローしたいと思います。なぜなら、フィルタリングして続行するのではなく、このケースを十分に考慮しているからです。 –

+1

一般に、LINQを使用する場合、元のソースコレクションはクエリ全体を通して_once_で繰り返し処理されます。値は各フィルタでただ通過します。 –

+0

これについての詳しい情報はどこで入手できますか、それをどのようにテストできますか?ありがとう。 –