2

I have a class.

DataMapper<TDalType, TFieldType> : DataMapperBase

For a particular entity, I have a

ObjectADataMapper<TFieldType> : DataMapper<ObjectADal, TFieldType>

I then have an instance of a DataMapperBase and need to determine if it is an entity that is a version of ObjectADataMapper (with any value of TFieldType).

AJ Henderson
  • 1,120
  • 1
  • 12
  • 32
  • What if you have `DerivedObjectADataMapper : ObjectADataMapper`, would you still want this to be picked up or only direct instances of `ObjectADataMapper`? – Chris Sinclair May 03 '13 at 20:21
  • @ChrisSinclair - I don't believe there should be an additional level of derivation, however any level of derivation should work probably. – AJ Henderson May 03 '13 at 20:28
  • possible duplicate of [Check if a class is derived from a generic class](http://stackoverflow.com/questions/457676/check-if-a-class-is-derived-from-a-generic-class) – AJ Henderson May 03 '13 at 20:31
  • I've voted to close this as duplicate of something else I had found earlier and was unsure how to use. I was missing the fact that I could do something like "typeof(ObjectADataMapper<>)". – AJ Henderson May 03 '13 at 20:32

3 Answers3

6

You can check this by seeing if the object's type is generic and if the corresponding generic template is the generic template that you are looking for. For example:

var type = obj.GetType();
bool isObjectADataMapper = type.IsGenericType && type.GetGenericTypeDefinition() == typeof(ObjectADataMapper<>);

Or, in a reusable way

  bool IsInstanceOfGenericTypeClosingTemplate(object obj, Type genericTypeDefinition){ 
      if(obj == null) throw new ArgumentNullException("obj");
      if(genericTypeDefinition== null) throw new ArgumentNullException("genericTypeDefinition");
      if(!genericTypeDefinition.IsGenericTypeDefinition) throw new ArgumentException("Must be a generic type definition.", "genericTypeDefinition");
      Type type = obj.GetType(); 
      return type.IsGenericType && type.GetGenericTypeDefinition() == genericTypeDefinition;
  }

You could even take this further and see if the type is derived from the generic type definition in question. For example, consider that you have:

  public class StringDataMapper : ObjectADataMapper<string>
  { 
     // .... whatever
  }

In this case the method I provided would fail. So you'd have to do something like

  bool IsInstanceOfGenericTypeClosingTemplateOrSubclassThereof(object obj, Type genericTypeDefinition){ 
      if(obj == null) throw new ArgumentNullException("obj");
      if(genericTypeDefinition== null) throw new ArgumentNullException("genericTypeDefinition");
      if(!genericTypeDefinition.IsGenericTypeDefinition) throw new ArgumentException("Must be a generic type definition.", "genericTypeDefinition");

      Type type = obj.GetType();
      while ( type != typeof(object) )
      {
         if(type.IsGenericType && type.GetGenericTypeDefinition() == genericTypeDefinition) 
         {
            return true;
         }
         type = type.BaseType;
      } 
      return false;
  }
smartcaveman
  • 41,281
  • 29
  • 127
  • 212
  • @ChrisSinclair, the "clever" way is to use an abstract non-generic base with an `internal` ctor, and only let the generic type definition in question inherit from it. Then you can do `is ObjectADataMapperBase`, and know safely that any concrete type must implement the generic `ObjectADataMapper<>`. Alternatively, you could use metadata (e.g. use an `internal` attribute, decorate the generic type definition with that attribute, and write a public extension method that tells whether the type has that attribute.) – smartcaveman May 03 '13 at 20:36
0

you need to get an instance of the type like so:

var typeToTestFor = typeof(ObjectADataMapper<>);

and a generic type for the object being tested

var typeOfObject being tested = objectBeingTested.GetType().GetGenericTypeDefinition();

together you can do the following

public bool IsObjectADataMapper(DataMapperBase base) {
  var typeUnderTest = base.GetType();
  if (!typeUnderTest.IsGenericType())
    return false; // its not generic so it can't match
  var typeToTestFor = typeof(ObjectADataMapper<>);
  return typeToTestFor.Equals(typeUnderTest.GetGenericTyepDefinition());
}
Charles Lambert
  • 5,042
  • 26
  • 47
-1

You can use is

if(obj is DataMapper)
{

}
Eric
  • 19,525
  • 19
  • 84
  • 147
  • That won't work because I need to know if it is a version of ObjectADataMapper, not any DataMapper. It could be an ObjectBDataMapper or an ObjectCDataMapper (or any other object) in which case the check should fail. – AJ Henderson May 03 '13 at 20:19