Testing If Object Is of Generic Type in C#

Testing if object is of generic type in C#

If you want to check if it's an instance of a generic type:

return list.GetType().IsGenericType;

If you want to check if it's a generic List<T>:

return list.GetType().GetGenericTypeDefinition() == typeof(List<>);

As Jon points out, this checks the exact type equivalence. Returning false doesn't necessarily mean list is List<T> returns false (i.e. the object cannot be assigned to a List<T> variable).

Determine if object is an instance of a generic base class, any generic type

The problem is that DrevidedC1 is not a sublcass of Class1<T>, it's a subclass of Class1<int>. Make sure you understand this subtle diference; Class1<T> is a open type (T can be anything, it hasn't been set) while DerivedC1 extends a closed type Class1<int> (it's not open in T anymore, T is set to int and only int). So when you do the following:

 typeof(DerivedC1).IsSubclassOf(typeof(Class1<>))

The answer is evidently false.

What you need to do is check if the generic type definition of DerivedC1's base type (think of it as the corresponding open generic type of Class1<int>) equals Class1<T> which it clearly does.

The correct code is therefore:

typeof(DerivedC1).BaseType.GetGenericTypeDefinition() == typeof(Class1<>));

Or better yet, as Matías Fidemraizer states in his answer:

typeof(DerivedC1).BaseType.GetGenericTypeDefinition().IsAssignableFrom(typeof(Class1<>)));

Check if object is of generic type with multiple type arguments

If you want to know whether the type is a generic InstantFeedbackCollectionViewModel you can use this code :

bool isInstantFeedbackCollectionViewModel = 
datagrid.ItemsSource.GetType().GetGenericTypeDefinition() ==
typeof(InstantFeedbackCollectionViewModel<,,>);

If you want to know whether the type inherits from a generic InstantFeedbackCollectionViewModel then see Check if a class is derived from a generic class.

Check whether an object is from a generic type(regardless of generic parameters types)

You may use a reflection for that and check that underlying Key type is generic and has a Pair<,> generic definition

public override string ToString()
{
var type = Key.GetType();
if (type.IsGenericType && type.GetGenericTypeDefinition().Equals(typeof(Pair<,>)))
{
return $"{Key} which is the key to {Value}";
}
return $"{Key} is the key to {Value}";
}

Key is Pair<object, object> will work only when T and U have object type, because in C# classes doesn't support a generic variance (only interfaces and delegates have such possibility)

Unit testing when generic type is needed

Currently AutoFixture doesn't support non-closed generic types activation and it's unlikely it will change one day.

Firstly it's caused by the fact that the C# language itself supports non-closed generic types for the reflection purpose only. You cannot declare variable of MyClass<> type without closing the type over particular T. Hence, even if AutoFixture substitute type and activate an instance for you, it will be hard to work with the result - you'd either need to use a variable of object type or rely on covariance if your type supports that. None of those options looks usable.

Secondly, the task itself is very hard as generic type could have constrains. Sometimes constrains could get crazy and e.g. have cyclic dependencies: class MyClass<T1, T2> where T1 : T2 where T2 : IEnumerable<T1>. The AutoFixture.Idioms library already tries to solve that problem for the GuardClauseAssertion, but the success is average. This feature requires dynamic type generation (which BTW is not supported on all the platforms) and very advanced usage of the Reflection.Emit API, which makes it very hard to implement correctly.



Related Topics



Leave a reply



Submit