2

文字列プロパティを持つクラスがあります。nullの可能性があるため、読み取るときに合体演算子を使用しますが、それでもNullRefrenceExeptionがスローされます。

string name = user.Section.ParentSection.Name ?? string.Empty;

より具体的には、「.ParentSection」がnullなので、「.name」さえないためですか?その場合、最初に if ブロックで ".ParentSection" をテストする必要がありますか?

Coalesce オペレーターについて、私が理解できない何かがあると思います。

4

9 に答える 9

7

より具体的には、「.ParentSection」がnullなので、「.name」さえないためですか?

はい。

その場合、最初に if ブロックで ".ParentSection" をテストする必要がありますか?

はい。

于 2012-03-28T14:49:53.823 に答える
4

SectionParentSectionが nullかどうかを確認する必要があります。これには if ステートメントを使用するか、次のような拡張メソッドを記述できます。

public static class MaybeMonad
{
    public static TOut With<TIn, TOut>(this TIn input, Func<TIn, TOut> evaluator)
        where TIn : class
        where TOut : class
    {
        if (input == null)
        {
            return null;
        }
        else
        {
            return evaluator(input);
        }
    }
}

このメソッドは次のように使用します。

string name = user.With(u => u.Section)
                  .With(s => s.ParentSection)
                  .With(p => p.Name) ?? string.Empty;

.がたくさんある if ステートメントよりもずっときれいだと思います&&

さらに読む: http://www.codeproject.com/Articles/109026/Chained-null-checks-and-the-Maybe-monad

于 2012-03-28T14:59:17.417 に答える
3

のプロパティで null 合体演算子を使用する前にuser、 、user.Section、またはが nullかどうかを確認する必要があります。user.Section.ParentSectionuser.Section.ParentSection

于 2012-03-28T14:50:32.440 に答える
3

nullアクセスされたオブジェクトのいずれかが をスローする場合、ネストされたプロパティ アクセスは安全ではありませんNullReferenceException。外側のオブジェクトが null でないことを明示的にテストする必要があります。

例えば:

string name = string.Empty;
if(user!=null && user.Section!=null && user.Section.ParentSection !=null)
   name = user.Section.ParentSection.Name ?? string.Empty;

一般に、プロパティへのネストされたアクセスを回避しようとします。Demeter の法則に違反しています。一部のリファクタリングにより、そもそもこれが不要になる場合があります。

于 2012-03-28T14:50:47.407 に答える
2

??演算子は左側が null かどうかをチェックし、そうである場合は右側を返し、そうでない場合は左側を返します。あなたの場合、左側はオブジェクトの「名前」プロパティでありuser.Section.ParentSection、これはnullです。

そのような場合、何が null であるかを考えるか、次のようにします。

string name = user == null 
              || user.Section == null 
              || user.ParentSection == null 
              || user.Section.ParentSection.Name == null 
                 ? string.Empty 
                 : user.Section.ParentSection.Name;

(ええ、それは私が知っている醜いです)

于 2012-03-28T14:52:11.073 に答える
1

userまたはuser.Sectionまたはがuser.Section.ParentSectionnull 値である可能性があります。

オペレーターは、次の??ようなチェックを妨げません。

if (user != null && user.Section != null && user.Section.ParentSection != null){

文字列プロパティまでのすべてが有効で存在することを確認してから、 を使用できます??(null).Name何度試しても を呼び出すことはできません。

于 2012-03-28T14:50:50.943 に答える
0

null 合体演算子は、次のようなステートメントを取ります。

a = b ?? c;  

これは、「b を評価し、null 以外の値がある場合は、それを a に割り当てます。そうでない場合は、c の値を a に割り当てます」ということです。

ただし b内では、nullの可能性がある名前プロパティを持つnullの可能性のある親セクションプロパティを持つnullの可能性があるセクションオブジェクトを持つnullの可能性があるユーザーオブジェクトを使用しています。これらすべてをチェックしたい場合 (通常はチェックする必要があります)、次のようにすることができます。

string name = string.Empty;  
if (user != null &&  
     user.Section != null &&  
     user.Section.ParentSection != null)  
{  
  name = user.Section.ParentSection.Name ?? string.Empty;  
}

IF チェックが失敗すると、それ以上のチェックは行われないため、オブジェクトが存在すると仮定してそのプロパティの 1 つにアクセスしようとしても、NullReferenceException は発生しません。

于 2012-03-28T15:04:41.140 に答える
0

はい、チェックする前に または nullかどうSectionかをチェックする必要がありますParentSectionName

于 2012-03-28T14:53:09.883 に答える
0

おそらく、次のようなことを行うのが最善です。

if(user!=null && user.Section!=null && user.Section.ParentSection!=null)
{
     string name = user.Section.ParentSection.Name ?? string.Empty;
}
于 2012-03-28T14:53:40.373 に答える