これは拡張メソッドであるため、チェーンのメンバーの1つがnullであっても正常に機能します。オブジェクトがパラメータとして渡されるメソッド呼び出しの構文糖衣であるため、null参照で拡張メソッドを呼び出すことができます。ただし、結果が。の場合、最後のNullReferenceException
ようにプロパティにアクセスしようとすると、が表示されます。.Name
null
チェーン呼び出しを使用して一連のパラメーターを収集し、最後にそれらを「処理」するだけの場合は、LINQと同様のパターンが必要です。中間型は、チェーン内の値を単に収集するある種のラッパーである必要があります。次に、タイプを照合するプロセスを実際に開始する最後の呼び出し、つまりのようなものが必要.Resolve()
です。これが呼ばれる実装例TypeChain
です:
public class TypeChain
{
private List<Type> types;
public TypeChain(Type t)
{
types = new List<Type>();
types.Add(t);
}
// searching for common base class (either concrete or abstract)
public TypeChain FindBaseClassWith(Type typeRight)
{
this.types.Add(typeRight);
return this;
}
public Type Resolve()
{
// do something to analyze all of the types
if (types.All (t => t == null))
return null;
else
types = types.Where (t => t != null).ToList();
var temp = types.First();
foreach (var type in types.Skip(1))
{
temp = temp.FindBaseClassWithHelper(type);
}
return temp;
}
}
FindBaseClassWith
静的実装にはいくつかの変更があります。
// searching for common base class (either concrete or abstract)
public static Type FindBaseClassWithHelper(this Type typeLeft, Type typeRight)
{
if(typeLeft == null || typeRight == null) return null;
return typeLeft
.GetClassHierarchy()
.Intersect(typeRight.GetClassHierarchy())
.FirstOrDefault(type => !type.IsInterface);
}
// searching for common base class (either concrete or abstract)
public static TypeChain FindBaseClassWith(this Type typeLeft, Type typeRight)
{
return new TypeChain(typeLeft).FindBaseClassWith(typeRight);
}
上記のチェーンロジックを使用すると、元のコードでは不可能なロジックシナリオが可能になります。すべてのエントリがであるかどうかを確認してからnull
戻ることができるようになりました。そうでない場合は、結果を汚染しないように、処理する前にすべてのエントリを最初にパージすることができます。もちろん、これは任意のロジックに拡張できます。null
null
null