2017-01-20 20 views
4

具体的には、bool?に関連し、返信方法をboolとすることで、ヌル伝播に注意を促しています。たとえば、次の点を考慮します。ヌル伝播が一貫して伝播しない理由Nullable <T>?

public static bool IsAttributedWith<TAttribute>(this JsonProperty property) 
    where TAttribute : Attribute 
{ 
    return property?.AttributeProvider 
        .GetAttributes(typeof(TAttribute), false) 
        .Any(); 
} 

これはコンパイルされませんし、次のエラーが存在する:

は、暗黙的にブール値に変換することができませんか?ブールに明示的な変換が存在します(キャストがありません)?

これは、私が.Any().GetValueOrDefault()を言うことができることを前提としていますよう、bool?ような方法の全身を治療しているが、これは.Any()戻りboolないbool?として許されないことを意味します。

私は私の周りの仕事として、次のいずれかの操作を行うことができることを知っている:

public static bool IsAttributedWith<TAttribute>(this JsonProperty property) 
    where TAttribute : Attribute 
{ 
    return property?.AttributeProvider 
        .GetAttributes(typeof(TAttribute), false) 
        .Any() 
     ?? false; 
} 

それとも

public static bool IsAttributedWith<TAttribute>(this JsonProperty property) 
    where TAttribute : Attribute 
{ 
    var any = 
     property?.AttributeProvider 
       .GetAttributes(typeof(TAttribute), false) 
       .Any(); 

    return any.GetValueOrDefault(); 
} 

それとも

public static bool IsAttributedWith<TAttribute>(this JsonProperty property) 
    where TAttribute : Attribute 
{ 
    return property?.AttributeProvider 
        .GetAttributes(typeof(TAttribute), false) 
        .Any() 
     ?? false; 
} 

私の質問は、なぜ私がすることはできません.Any()呼び出しで直接.GetValueOrDefault()チェーンを呼び出しますか?

public static bool IsAttributedWith<TAttribute>(this JsonProperty property) 
    where TAttribute : Attribute 
{ 
    return (property?.AttributeProvider 
        .GetAttributes(typeof(TAttribute), false) 
        .Any()) 
        .GetValueOrDefault(); 
} 

私は、値が実際にbool?この時点ではなくboolであるとして、これは理にかなって思います。

+1

をあなたは括弧をつけなければならないので、.'条件呼び出しチェーン知られている演算子を、終了: '(property?.AttributeProvider.GetAttributes(typeof(TAttribute)、false).Any())。GetValueOrDefault()'。 – PetSerAl

+0

'property'がnullの場合、メソッドはnullを返そうとします。しかし、返り値の型は 'bool'なので、null型ではありません。戻り値の型を 'bool? 'に変更してください。 – Abion47

答えて

5

?.オペレータの後に続くすべてのコールチェーンは、条件付き即時コールとして解釈されません。 、

property==null ? (bool?)null : property.AttributeProvider 
             .GetAttributes(typeof(TAttribute), false) 
             .Any() 
             .GetValueOrDefault() 

、それは失敗しますAny()リターンboolないbool?ので:だから、このコードは:あなたがGetValueOrDefault()を追加する場合

property?.AttributeProvider 
     .GetAttributes(typeof(TAttribute), false) 
     .Any() 

property==null ? (bool?)null : property.AttributeProvider 
             .GetAttributes(typeof(TAttribute), false) 
             .Any() 

と解釈します。したがって、あなたはここに括弧を使用する必要があります。

(property==null ? (bool?)null : property.AttributeProvider 
             .GetAttributes(typeof(TAttribute), false) 
             .Any()) 
             .GetValueOrDefault() 

同じカッコあなたが?.演算子を使用するときに使用する必要があります? `

(property?.AttributeProvider 
      .GetAttributes(typeof(TAttribute), false) 
      .Any()) 
      .GetValueOrDefault() 
2

GetValueOrDefaultAny()メソッドの呼び出し時にコールが実行され、boolが返されます。全身の結果に対して実行したい場合は、カッコで囲む必要があります。

return (property?.AttributeProvider 
       .GetAttributes(typeof(TAttribute), false) 
       .Any()) 
       .GetValueOrDefault(); 

ヌル条件演算子は、短絡演算子であり、したがって、オブジェクトがnullの場合、オブジェクトまたはそのプロパティまたはメソッドで実行しようとしているドットの右側に何も実行されません。したがって、文全体でコードを実行するには、何らかの方法でラップする必要があります(かっこや別のオブジェクトを使用する)。

+0

私はあなたがかっこをすることができることを知っています。しかし、それは私が求めていることではありません。 C#は文全体を 'bool? 'と扱っていますが、' bool?'のように扱うことはできません。私はそれが何をしているのか知っている、私はなぜ尋ねている。 –