2017-08-15 3 views
0

IListのうちの1つ(どちらか一方または両方)にnullを含めることができます。両方がnullの場合、結果はnullになります。2つのIListsを安全に組み合わせて、ヌルを考慮に入れて

私はこれを持っていますが、私はもっとエレガントですが、読んでも簡単です。

private IList<Filter> CombineFilters(IList<Filter> first, IList<Filter> second) 
{ 
    IList<Filter> result = null; 

    if(first != null) 
     if (second != null) 
      result = first.Concat(second) as IList<Filter>; 
     else 
      result = first; 
    else if (second != null) 
     result = second; 

    return result; 
} 
+1

コードが動作しているように見えるので、コードレビューの方が良いかもしれません。とにかく正しい結果であると判明した場合(なぜ 'else if'なのか)、' result'に 'null'を代入しないようにしようとしているのはなぜですか? –

+1

as IList の代わりに 'first.Concat(second).ToList()'が必要です。そうでなければ結果はnullになります –

+0

@Damien_The_Unbeliever 'else if'は' first'が 'null'で' second' 'は – Bobbler

答えて

3

私は二つのリスト(1 nullの可能性がある)を使用してCombineFiltersを呼び出し、そのリストを取り戻す場合、それは奇妙な行動の少しだと思うだろうではなく、です。その結果、次のような動作が発生します。

List<Filter> filters1 = new List<Filter>() { new Filter() }; 
List<Filter> filters2 = null; 

Console.WriteLine(filters1.Count); // 1 

var filters = CombineFilters(filters1, filters2); 
filters.Add(new Filter()); 

Console.WriteLine(filters.Count); // 2 
Console.WriteLine(filters1.Count); // also 2 

実際にこの動作が期待されるかどうかはわかりません。

最後に新しいリストがあることを常に確認することをお勧めします。

private IList<Filter> CombineFilters(IList<Filter> first, IList<Filter> second) 
{ 
    return (first ?? Array.Empty<Filter>()).Concat(second ?? Array.Empty<Filter>()).ToList(); 
} 
+0

エレガントな答えをありがとう。なぜ新しいリストを持っているのですか?私は、必要に応じてインスタンス化するほうが好きです。 – Bobbler

+1

必ずしも良いとは限りませんが、より一貫した経験が得られます。メソッドが 'IList'を返すので、私はそれを変更することができると期待します。おそらく変更は私の元のリストに影響を与えないはずです。あなたが 'IEnumerable'を返すのであれば、これは避けることができます。なぜなら、それは設計によって変更できないからです。 – poke

1
private IList<Filter> CombineFilters(IList<Filter> first, IList<Filter> second) 
{ 
    if (first == null && second == null) return null; 
    first = first ?? new List<Filter>(); 
    second = second ?? new List<Filter>(); 
    return first.Concat(second).ToList(); 
} 
+0

'Enumerable.Empty ()'はどうでしょうか? – haim770

+0

私はそのビットを見逃しました。コントラクトが入力時にnull-is-emptyであるが、出力に対してnullを返す関数を持つのはちょっと奇妙だと思う。 – Puppy

3

一緒??オペレータと利用Enumerable.Concate

if(first == null && second == null) 
    return null; 
return Enumerable.Concat(first ?? Enumerable.Empty<IFilter>(), 
         second ?? Enumerable.Empty<IFilter>()).ToList(); 

いずれかfirstまたはsecondは、連結のために代わりに使用される新しいリストnullしている場合。


私は場合には、両方のリストがnullその後、まだ初期化コレクションが返されるべきだと思います。その場合はif文だけを削除してください。また、多分代わりIListIEnumerableを返す:代わりにIListIEnumerableを返す

private IEnumerable<Filter> CombineFilters(IEnumerable<Filter> first, IEnumerable<Filter> second) 
{ 
    return Enumerable.Concat(first ?? Enumerable.Empty<IFilter>(), 
          second ?? Enumerable.Empty<IFilter>()); 
} 

はあなたのシナリオに依存します。詳細はこちらを読む:

1

あなたはこのような何かを行うことができます:これは、あなたが、これは本当に短い行うことができます

、それは完全にヌルコレクションを避けることをお勧めだと述べて
private IList<Filter> CombineFilters(IList<Filter> first, IList<Filter> second) 
{ 

    if (first == null && second == null) 
    { 
     return null; 
    } 

    return (first ?? Enumerable.Empty<Filter>()) 
      .Concat(second ?? Enumerable.Empty<Filter>()) 
      .ToList(); 
} 

。要素がない場合は、空のコレクションを返します。この方法では、常にNULLをチェックする必要はありません。これはあなたのケースでは可能ではないかもしれませんが、そうであれば、コードをきれいにするでしょう。それは、より一般的な抽象化であるとして

また、IList<T>いうしIEnumerable<T>を使用することを検討してください(ともIList<T>が壊れ、漏れやすい抽象化ですので、 - 実装は(例外を投げる)、彼らはサポートしていないメソッドのために!)。一方、これはプライベートメソッドであることがわかります。実際には常にList<Filter>を渡している場合は、パラメータをList<Filter>と宣言する方がよいでしょう。

EDIT:
私の答えは、私が以前見たことがなかったGilad Greenによって投稿されたoneと非常に似ています。

+0

'IList 'はどのように漏れていますか? – Bobbler

+0

@Bobbler:それ自体のメリットでは、IList はOKですが、.NET Frameworkの以前のバージョンでは、「コレクション」という概念の抽象として多かれ少なかれ扱われていました。したがって、.NET 2.0の多くのコレクションでは、IList が実装されていますが、それらの多くはインターフェイスによって定義されたメソッドの重要なサブセットをサポートしていません。彼らの解決策は 'NotSupportedException' -sを投げることでした。これはかなり恐ろしいことです。これはLiskovのサブジェクトの原則に違反し、 'IList 'の有用性を低下させます。そして、コレクションは実際にあなたが列挙できるものだと分かりました( 'IEnumerable ')。 –

関連する問題