3

Suppose I have a class

public class Entity<T> { ... // class definition ... }

And say I have bit of code like:

var a = new Entity<string>();
var b = new Entity<int>();
var c = new Entity<bool>();
var d = new int;
var e = new List<string>();

How do I test that an object is of type "Entity" regardless of the type of T? Such that:

a is Entity    // true
b is Entity    // true
c is Entity    // true
d is Entity    // false
e is Entity    // false

4 Answers4

0

You can compare the Generic type definition of the variable to the generic type definition of your Entity class.

Type genericType = typeof(Entity<>);

var a = new Entity<string>();

bool isAOfTypeEntity =
    a.GetType().IsGenericType &&
    a.GetType().GetGenericTypeDefinition() == genericType;

// returns true.

Note that, we first check with IsGenericType, otherwise GetGenericTypeDefinition throws an error.

Please also check for null first. You can refactor all this into a method, I think.

There can be faster or better ways and I will be happy to see them, if provided.

Hope this helps.

Oguz Ozgul
  • 6,809
  • 1
  • 14
  • 26
0

If you are not concerned with the generic type when you want to check if it is an entity, you could add an extra class.

public class Entity { } // If you want, you can make it abstract.
public class Entity<T> : Entity { ... // class definition ... }

var a = new Entity<string>();
var b = new Entity<int>();
var c = new Entity<bool>();
var d = new int;
var e = new List<string>();

a is Entity    // true
b is Entity    // true
c is Entity    // true
d is Entity    // false
e is Entity    // false
Silvermind
  • 5,791
  • 2
  • 24
  • 44
0

If you're in an environment where you don't care too much about performance then reflection can be a solution for you. However, I'd recommend not using reflection and instead having Entity<T> inherit from a non-generic type of Entity or IEntity (see Silvermind's answer).

For reflection these extension methods should allow you to check against typeof(Entity<>) (the optional boolean argument defaults to checking base types too):

static bool IsInstanceOfGenericType(this object item, Type @type, bool includeBaseTypes = true) {
    return item.GetType().IsBasedOnGenericType(@type, includeBaseTypes);
}

static bool IsBasedOnGenericType(this Type t, Type @type, bool includeBaseTypes = true) {
    return (t.IsGenericType && t.GetGenericTypeDefinition() == @type)
            || includeBaseTypes
                && (t.GetInterfaces().Any(i => IsBasedOnGenericType(i, @type))
                    || (t.BaseType != null ? IsBasedOnGenericType(t.BaseType, @type) : false));
}

The IsInstanceOfGenericType method can be used as so:

class InheritingClass : Entity<string> { }
class Entity<T> : IEntity<T> { }
interface IEntity<T> { }

var item = new InheritingClass();
var item2 = new Entity<string>();
var item3 = new Entity<string>();
var item4 = new List<string>();
var item5 = new InheritingClass();

Console.WriteLine( "item: " + item.IsInstanceOfGenericType(typeof(Entity<>)) );
Console.WriteLine( "item2: " + item2.IsInstanceOfGenericType(typeof(Entity<>)) );
Console.WriteLine( "item3: " + item3.IsInstanceOfGenericType(typeof(IEntity<>)) );
Console.WriteLine( "item4: " + item4.IsInstanceOfGenericType(typeof(IEntity<>)) );
Console.WriteLine( "item5: " + item5.IsInstanceOfGenericType(typeof(Entity<>), false) );

item: True
item2: True
item3: True
item4: False
item5: False
Kana Ki
  • 179
  • 1
  • 5
0

This works:

public class Entity<T>
{ 
}

static class Program
{
    static void Main(string[] args)
    {
        var a = new Entity<string>();
        var b = new Entity<int>();
        var c = new Entity<Point>();
        var e = 1001;
        var f = new List<int>();

        if (a.IsEntity())
        {
            Debug.WriteLine($"{nameof(a)} is an Entity");
        }
        if (b.IsEntity())
        {
            Debug.WriteLine($"{nameof(b)} is an Entity");
        }
        if (c.IsEntity())
        {
            Debug.WriteLine($"{nameof(c)} is an Entity");
        }
        if (e.IsEntity())
        {
            Debug.WriteLine($"{nameof(e)} is an Entity");
        }
        if (f.IsEntity())
        {
            Debug.WriteLine($"{nameof(f)} is an Entity");
        }
    }

    static bool IsEntity(this object obj)
    {
        var t = obj.GetType();
        if (t.IsGenericType)
        {
            return typeof(Entity<>).IsAssignableFrom(t.GetGenericTypeDefinition());
        }
        return false;
    }
}
John Alexiou
  • 28,472
  • 11
  • 77
  • 133