1

foreachこれよりも、NullReference例外からループを保護するためのよりスマートな方法はありますか?

if (G_Locatie.OverdrachtFormulierList != null)
{
    foreach (OverdrachtFormulier otherform in G_Locatie.OverdrachtFormulierList)
    {
        ...
    }
}

多くの場合ネストされた多くのforeachループと、たとえばG_Locationが確かに存在する多くの変数を使用しますが、datamember.OverdrachtFormulierListにはnewまだリストの使用が割り当てられていない可能性があります。


親愛なる友人、すべてのコメントに感謝します。あなたの提案のアイデアを得た後、正確に理解するのに多くの問題を抱えながら、私が取り組むようになったラザニアのコードを掘り下げた後、そしていくつかの実験の後、私は最も簡単でクリーンな方法は単にNULLを避けることです、適切な初期化によって。コードでOverdrachtFormulierListを初期化する必要はありませんが、1つのインスタンスを忘れるリスクがありますが、初期化の適切な場所、つまり元のクラス定義を見つけました。

簡単にするために、次のコードを見てください。

    class MyClass
    {
        public List<string> items = new List<string>();

        public IEnumerator<string> GetEnumerator()
        {
            return items.GetEnumerator();
        }
    }

    class MyComplexClass
    {
        private MyClass _itemlist /*= new MyClass()*/;
        public MyClass itemlist
        {
            get { return _itemlist; }
            set { _itemlist = value; }
        }
    }

    void Sandbox()
    {
        MyClass mc /*= new MyClass()*/;
        foreach (string Sb in mc.items)
        {
            string x = Sb;
        }

        MyComplexClass mcc = new MyComplexClass();
        foreach (string Mb in mcc.itemlist) // <--- NullReferenceException
        {
            string x = Mb;
        }

        return;
    }

楽しいのは、C#が多くのバグのある間違いからあなたを保護しているように見えることです。で初期化のコメントを解除しないと、このコードはビルドされないSandbox()ため、最初のコードは。foreachを取得しませんNullReferenceException

MyComplexClassただし、 2番目の例外を回避するために、initのコメントを解除することをお勧めしますforeach。C#は、この初期化の有無にかかわらずビルドされます。

したがって、実際のコードでは、G_Locatieのクラス定義に単純な初期化を追加するだけで済みます。

現在の唯一の問題は、上記のコードを常に単純化したかったのです{get; set;}が、説明したように初期化ではそれが不可能になることです。私はその小さな問題に耐えなければなりません。

実際、オブジェクトタイプのプロパティでは、セッターは実際には必要ありません。

最後に、自分の問題に適切なタイトルが見つからないことに気づきました。これまでのところ、私が抱えていたすべての問題はこのフォーラムですでに回答されており、これに似た投稿が見つからなかったという理由だけで、今日投稿しなければならなかったと感じています。おそらく誰かがこのソリューションを見つけやすくするタイトルとタグを思い付くことができます。

4

2 に答える 2

6

はい、コレクション プロパティは null ではなく空のコレクションを返す必要があります。これを確実にする 1 つの方法は、バッキング フィールドを使用し、ゲッターで新しいリストを割り当てることです。

private List<string> overdrachtFormulierList;

public List<string> OverdrachtFormulierList 
{
     get
     {
        return this.overdrachtFormulierList ?? 
            (this.overdrachtFormulierList = new List<string>());
     }

     set
     {
        this.overdrachtFormulierList = value;
     }
}

あなたEnumerable.Empty<T>のタイプがIEnumerable<T>

于 2013-03-13T10:46:47.087 に答える
5

1 つのオプションは、拡張メソッドを作成することです。

public static IEnumerable<T> EmptyIfNull<T>(this IEnumerable source)
{
    return source ?? Enumerable.Empty<T>();
}

それで:

foreach (var otherform in G_Locatie.OverdrachtFormulierList.EmptyIfNull())
{
    ...
}

null 参照の代わりに常に空のコレクションを使用することをお勧めします。

于 2013-03-13T10:47:22.290 に答える