Since it's an extension method, it will work fine even if one of the members of the chain is null. You can call extension methods on a null reference because it's syntactic sugar for a method call where the object is passed as a parameter. However, you will get a NullReferenceException
if you try to access a property like .Name
at the end when the result is null
.
If you want to use a chain call to collect a series of parameters, and then only "process" them at the end, you want a similar pattern to LINQ. The intermediate types should be some sort of a wrapper that simply collects the values in the chain. Then there should be a final call that actually initiates the process of matching the types, i.e., something like .Resolve()
. Here's an example implementation called 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;
}
}
There would be a few changes to the FindBaseClassWith
static implementations:
// 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);
}
Using the chaining logic above allows for a logic scenario that isn't possible with the original code. It's now possible to check if all entries are null
, and then return null
, or if any are not null
, then purge all the null
entries first before processing so they don't pollute the result. This can be extended of course to any desired logic.