The TypeBuilder.CreateType()
method is defined as nullable:
public Type? CreateType();
Under what conditions can it return null? The docs do not say.
I could dig into the source, but that would yield an untrustworthy answer (though interesting). Is there a documented explanation for this signature which I've missed?
Inter-site-crosspost-ahoy: https://github.com/dotnet/dotnet-api-docs/issues/7955
Under what conditions can
TypeBuilder.CreateType()
returnnull
?
TL;DR: There is no situation when TypeBuilder.CreateType()
will return null
when CreateType()
is being called by user-code. You can safely add a null-forgiving !
to a CreateType()
call-site.
The current source is at https://github.com/dotnet/runtime/blob/1a296c06fff8750b4658f6f7d901347e006744d0/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/TypeBuilder.cs#L1853
TypeBuilder.CreateType()
only returns null
when the TypeBuilder
is the builder for an assembly's hidden <Module>
class.
<Module>
class is a special type that allows assemblies/modules to have eager-initialized globals.<Module>
, though other languages do (e.g. C++/CLI).<Module>
members via the [ModuleInitializer]
attribute.Reflection.Emit
then you will have always been able to use ModuleBuilder
going back to .NET 1.x in 2001.<Module>
-building TypeBuilder
instances cannot be directly instantiated by user-code as it requires a specific internal TypeBuilder()
constructor invocation - instead this ctor is called only when you use the ModuleBuilder
type.TypeBuilder.CreateType()
method does indeed return null
is inside void ModuleBuilder.CreateGlobalFunctions()
, which basically ensures that a class <Module>
will be defined in the generated dynamic-assembly.Type? TypeBuilder.CreateType()
's return-type is technically correct (the best kind of correct), it's only there because the current API design is poor: it uses a single method for two separate use-cases when one of those cases is also internal
-only.