I have an application that uses many types of derived classes from a common base class, and several of the derived classes use generics. The application often needs to iterate through collections of the derived classes and identify specific class types for special processing.
The problem is how to test for a specific generic derivative of a base class without knowing the type, in a concise and elegant way ( since it is done often in the project ) ?
The 'is' operator won't work for this:
if (item is MyDerivedGenericClass<>) // Won't compile
To work around this problem, I am considering using empty Marker Interfaces to identify the special classes within a collection. This seems to be the cleanest solution.
A couple of notes:
An example below:
public interface MarkerA { } // Empty Interface
public interface MarkerB { } // Empty Interface
public interface MarkerC { } // Empty Interface
public class BaseClass { }
public class DerivedClassA : BaseClass { }
public class DerivedClassB : BaseClass { }
public class DerivedClassC : BaseClass { }
public class DerivedSpecialClass : BaseClass { }
public class DerivedSpecialA : DerivedSpecialClass { }
public class DerivedSpecialB : DerivedSpecialClass { }
public class DerivedSpecialC : DerivedSpecialClass { }
public class DerivedSpecialGenericA<T> : DerivedSpecialClass, MarkerA { }
public class DerivedSpecialGenericB<T> : DerivedSpecialClass, MarkerB { }
public class DerivedSpecialGenericC<T> : DerivedSpecialClass, MarkerC { }
public void ProcessClasses(List<BaseClass> list)
{
// Iterate through a list of mixed classes that all derive from BaseClass
foreach (BaseClass item in list)
{
// Ideal approach, but doesn't compile:
// Try to isolate select class types to do something interesting with
if ((item is DerivedSpecialA) || (item is DerivedSpecialB) || (item is DerivedSpecialGenericB<>))
{
var specialItem = item as DerivedSpecialClass;
DoSomethingInteresting(specialItem);
Console.WriteLine(specialItem.Title);
}
// Alternative workaround that tests for the Marker instead
// Try to isolate select class types to do something interesting with
if ((item is DerivedSpecialA) || (item is DerivedSpecialB ) || (item is MarkerB))
{
var specialItem = item as DerivedSpecialClass;
DoSomethingInteresting(specialItem);
Console.WriteLine(specialItem.Title);
}
}
}
Does anyone have any better ideas for how to approach this problem ?
Thanks.
When I need to write code that differs depending on the type of object, and that code is not practical as a virtual method, I use an identifier implemented as a virtual property returning immutable information. This is cleaner, and uses no additional instance storage, although it would be nice to initialize MarkerType via a type parameter.
public class BaseClass
{
public abstract MarkerType { get; }
}
public enum MarkerType { A, B, C }