I have a bunch of regular, closed and opened types in my assembly. I have a query that I'm trying to rule out the open types from it
class Foo { } // a regular type
class Bar<T, U> { } // an open type
class Moo : Bar<int, string> { } // a closed type
var types = Assembly.GetExecutingAssembly().GetTypes().Where(t => ???);
types.Foreach(t => ConsoleWriteLine(t.Name)); // should *not* output "Bar`2"
Upon debugging the generic arguments of an open type, I found that their FullName
is null (as well as other things like the DeclaringMethod
) - So this could be one way:
bool IsOpenType(Type type)
{
if (!type.IsGenericType)
return false;
var args = type.GetGenericArguments();
return args[0].FullName == null;
}
Console.WriteLine(IsOpenType(typeof(Bar<,>))); // true
Console.WriteLine(IsOpenType(typeof(Bar<int, string>))); // false
Is there a built-in way to know if a type is open? if not, is there a better way to do it? Thanks.
You could use IsGenericTypeDefinition
:
typeof(Bar<,>).IsGenericTypeDefinition // true
typeof(Bar<int, string>).IsGenericTypeDefinition // false
Type.IsGenericTypeDefinition is not technically the correct property to rule out open types. It will however work just fine in your case (and indeed in most other cases).
That being said, a type can be open without being a generic type definition. In the more general case, e.g. in a public method that accepts a Type parameter, what you really want is Type.ContainsGenericParameters.
For full details see the answer to this question:
Difference between Type.IsGenericTypeDefinition and Type.ContainsGenericParameters
TL;DR: The latter is recursive, while the former is not, and can thus be "fooled" by constructing a generic type that has a generic type definition as at least one of its generic type parameters.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With