C#6アップデート
// C#1-5
propertyValue1 = myObject != null ? myObject.StringProperty : null;
// C#6
propertyValue1 = myObject?.StringProperty;
以下の質問は古いバージョンにも当てはまりますが、新しい?.
演算子を使用して新しいアプリケーションを開発する場合は、はるかに優れた方法です。
元の質問:
nullの可能性のあるオブジェクトのプロパティに定期的にアクセスしたい:
string propertyValue1 = null;
if( myObject1 != null )
propertyValue1 = myObject1.StringProperty;
int propertyValue2 = 0;
if( myObject2 != null )
propertyValue2 = myObject2.IntProperty;
等々...
私はこれを頻繁に使用するので、スニペットがあります。
次の場合は、インラインでこれをある程度短縮できます。
propertyValue1 = myObject != null ? myObject.StringProperty : null;
ただし、これは少し不格好です。特に、多くのプロパティを設定する場合や、複数のレベルをnullにできる場合は、次のようになります。
propertyValue1 = myObject != null ?
(myObject.ObjectProp != null ? myObject.ObjectProp.StringProperty) : null : null;
私が本当に必要としているのは??
スタイル構文です。これは直接null型に最適です。
int? i = SomeFunctionWhichMightReturnNull();
propertyValue2 = i ?? 0;
だから私は次のことを思いついた:
public static TResult IfNotNull<T, TResult>( this T input, Func<T, TResult> action, TResult valueIfNull )
where T : class
{
if ( input != null ) return action( input );
else return valueIfNull;
}
//lets us have a null default if the type is nullable
public static TResult IfNotNull<T, TResult>( this T input, Func<T, TResult> action )
where T : class
where TResult : class
{ return input.IfNotNull( action, null ); }
これにより、次の構文が可能になります。
propertyValue1 = myObject1.IfNotNull( x => x.StringProperty );
propertyValue2 = myObject2.IfNotNull( x => x.IntProperty, 0);
//or one with multiple levels
propertyValue1 = myObject.IfNotNull(
o => o.ObjectProp.IfNotNull( p => p.StringProperty ) );
これにより、これらの呼び出しが簡略化されますが、この種の拡張メソッドをチェックインするかどうかはわかりません。コードが少し読みやすくなりますが、オブジェクトを拡張する必要があります。これはすべてに表示されますが、具体的に参照される名前空間に配置することもできます。
この例はかなり単純な例ですが、もう少し複雑な例では、2つのnull許容オブジェクトのプロパティを比較します。
if( ( obj1 == null && obj2 == null ) ||
( obj1 != null && obj2 != null && obj1.Property == obj2.Property ) )
...
//becomes
if( obj1.NullCompare( obj2, (x,y) => x.Property == y.Property )
...
このように拡張機能を使用する際の落とし穴は何ですか?他のコーダーは混乱する可能性がありますか?これは単に拡張機能の乱用ですか?
私がここで本当に欲しいのはコンパイラ/言語拡張だと思います:
propertyValue1 = myObject != null ? myObject.StringProperty : null;
//becomes
propertyValue1 = myObject?StringProperty;
これにより、複雑なケースがはるかに簡単になります。
propertyValue1 = myObject != null ?
(myObject.ObjectProp != null ? myObject.ObjectProp.StringProperty) : null
//becomes
propertyValue1 = myObject?ObjectProp?StringProperty;
これは値型に対してのみ機能しますが、null許容の同等物を返すことができます。
int? propertyValue2 = myObject?ObjectProp?IntProperty;
//or
int propertyValue3 = myObject?ObjectProp?IntProperty ?? 0;