Testing if object is of generic type in C# - Printable Version +- 0Day Forums (https://0day.red) +-- Forum: Coding (https://0day.red/Forum-Coding) +--- Forum: C# (https://0day.red/Forum-C) +--- Thread: Testing if object is of generic type in C# (/Thread-Testing-if-object-is-of-generic-type-in-C) |
Testing if object is of generic type in C# - tilliehzkggalvz - 07-24-2023 I would like to perform a test if an object is of a generic type. I've tried the following without success: public bool Test() { List<int> list = new List<int>(); return list.GetType() == typeof(List<>); } What am I doing wrong and how do I perform this test? RE: Testing if object is of generic type in C# - bacalao730607 - 07-24-2023 return list.GetType().IsGenericType; RE: Testing if object is of generic type in C# - Drbuttonhook4 - 07-24-2023 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). RE: Testing if object is of generic type in C# - Sirlied10 - 07-24-2023 I assume that you don't just want to know if the type is generic, but if an object is an instance of a particular generic type, without knowing the type arguments. It's not terribly simple, unfortunately. It's not too bad if the generic type is a class (as it is in this case) but it's harder for interfaces. Here's the code for a class: using System; using System.Collections.Generic; using System.Reflection; class Test { static bool IsInstanceOfGenericType(Type genericType, object instance) { Type type = instance.GetType(); while (type != null) { if (type.IsGenericType && type.GetGenericTypeDefinition() == genericType) { return true; } type = type.BaseType; } return false; } static void Main(string[] args) { // True Console.WriteLine(IsInstanceOfGenericType(typeof(List<>), new List<string>())); // False Console.WriteLine(IsInstanceOfGenericType(typeof(List<>), new string[0])); // True Console.WriteLine(IsInstanceOfGenericType(typeof(List<>), new SubList())); // True Console.WriteLine(IsInstanceOfGenericType(typeof(List<>), new SubList<int>())); } class SubList : List<string> { } class SubList<T> : List<T> { } } EDIT: As noted in comments, this may work for interfaces: foreach (var i in type.GetInterfaces()) { if (i.IsGenericType && i.GetGenericTypeDefinition() == genericType) { return true; } } I have a sneaking suspicion there may be some awkward edge cases around this, but I can't find one it fails for right now. RE: Testing if object is of generic type in C# - defenselesseseejvyokm - 07-24-2023 You can use shorter code using dynamic althougth this may be slower than pure reflection: public static class Extension { public static bool IsGenericList(this object o) { return IsGeneric((dynamic)o); } public static bool IsGeneric<T>(List<T> o) { return true; } public static bool IsGeneric( object o) { return false; } } var l = new List<int>(); l.IsGenericList().Should().BeTrue(); var o = new object(); o.IsGenericList().Should().BeFalse(); RE: Testing if object is of generic type in C# - almirabyus - 07-24-2023 These are my two favorite extension methods that cover most edge cases of generic type checking: Works with: - Multiple (generic) interfaces - Multiple (generic) base classes - Has an overload that will 'out' the specific generic type if it returns true (see unit test for samples): public static bool IsOfGenericType(this Type typeToCheck, Type genericType) { Type concreteType; return typeToCheck.IsOfGenericType(genericType, out concreteType); } public static bool IsOfGenericType(this Type typeToCheck, Type genericType, out Type concreteGenericType) { while (true) { concreteGenericType = null; if (genericType == null) throw new ArgumentNullException(nameof(genericType)); if (!genericType.IsGenericTypeDefinition) throw new ArgumentException("The definition needs to be a GenericTypeDefinition", nameof(genericType)); if (typeToCheck == null || typeToCheck == typeof(object)) return false; if (typeToCheck == genericType) { concreteGenericType = typeToCheck; return true; } if ((typeToCheck.IsGenericType ? typeToCheck.GetGenericTypeDefinition() : typeToCheck) == genericType) { concreteGenericType = typeToCheck; return true; } if (genericType.IsInterface) foreach (var i in typeToCheck.GetInterfaces()) if (i.IsOfGenericType(genericType, out concreteGenericType)) return true; typeToCheck = typeToCheck.BaseType; } } Here's a test to demonstrate the (basic) functionality: [Test] public void SimpleGenericInterfaces() { Assert.IsTrue(typeof(Table<string>).IsOfGenericType(typeof(IEnumerable<>))); Assert.IsTrue(typeof(Table<string>).IsOfGenericType(typeof(IQueryable<>))); Type concreteType; Assert.IsTrue(typeof(Table<string>).IsOfGenericType(typeof(IEnumerable<>), out concreteType)); Assert.AreEqual(typeof(IEnumerable<string>), concreteType); Assert.IsTrue(typeof(Table<string>).IsOfGenericType(typeof(IQueryable<>), out concreteType)); Assert.AreEqual(typeof(IQueryable<string>), concreteType); } |