TypeBuilder.CreateType Metoda
Definicja
Ważne
Niektóre informacje odnoszą się do produktu w wersji wstępnej, który może zostać znacząco zmodyfikowany przed wydaniem. Firma Microsoft nie udziela żadnych gwarancji, jawnych lub domniemanych, w odniesieniu do informacji podanych w tym miejscu.
Type Tworzy obiekt dla klasy . Po zdefiniowaniu pól i metod w klasie jest wywoływana w CreateType
celu załadowania jego Type
obiektu.
public:
Type ^ CreateType();
public Type? CreateType ();
public Type CreateType ();
member this.CreateType : unit -> Type
Public Function CreateType () As Type
Zwraca
Zwraca nowy Type obiekt dla tej klasy.
Wyjątki
Nie utworzono otaczającego typu.
-lub-
Ten typ nie jest abstrakcyjny i zawiera metodę abstrakcyjną.
-lub-
Ten typ nie jest abstrakcyjną klasą ani interfejsem i ma metodę bez treści metody.
Nieprawidłowa zawartość etykiety w pliku ILGenerator: Zdefiniowano etykietę bez wywoływania metody MarkLabel(Label).
Typ zawiera nieprawidłowy kod języka Microsoft Intermediate Language (MSIL).
-lub-
Element docelowy gałęzi jest określony przy użyciu przesunięcia 1-bajtowego, ale element docelowy znajduje się w odległości większej niż 127 bajtów od gałęzi.
Nie można załadować typu. Na przykład zawiera metodę, która ma konwencję static
HasThiswywoływania .
Przykłady
Poniższy przykład kodu pokazuje, jak zdefiniować procedurę obsługi zdarzeń dla AppDomain.TypeResolve zdarzenia, aby wywołać CreateType metodę w zagnieżdżonym typie podczas CreateType wywołania otaczającego typu.
using namespace System;
using namespace System::Reflection;
using namespace System::Reflection::Emit;
using namespace System::Threading;
using namespace System::Text;
using namespace System::Resources;
using namespace System::Collections;
using namespace System::IO;
// Helper class called when a resolve type event is raised.
ref class TypeResolveHandler
{
private:
Module^ m_Module;
public:
TypeResolveHandler( Module^ mod )
{
m_Module = mod;
}
Assembly^ ResolveEvent( Object^ sender, ResolveEventArgs^ args );
};
ref class NestedEnum
{
internal:
static TypeBuilder^ enumType = nullptr;
static Type^ tNested = nullptr;
static Type^ tNesting = nullptr;
public:
static void Main()
{
AssemblyName^ asmName = gcnew AssemblyName;
asmName->Name = "NestedEnum";
AssemblyBuilder^ asmBuild = Thread::GetDomain()->DefineDynamicAssembly( asmName, AssemblyBuilderAccess::RunAndSave );
ModuleBuilder^ modBuild = asmBuild->DefineDynamicModule( "ModuleOne", "NestedEnum.dll" );
// Hook up the event listening.
TypeResolveHandler^ typeResolveHandler = gcnew TypeResolveHandler( modBuild );
// Add a listener for the type resolve events.
AppDomain^ currentDomain = Thread::GetDomain();
ResolveEventHandler^ resolveHandler = gcnew ResolveEventHandler( typeResolveHandler, &TypeResolveHandler::ResolveEvent );
currentDomain->TypeResolve += resolveHandler;
TypeBuilder^ tb = modBuild->DefineType( "AType", TypeAttributes::Public );
TypeBuilder^ eb = tb->DefineNestedType( "AnEnum", static_cast<TypeAttributes>(TypeAttributes::NestedPublic | TypeAttributes::Sealed), Enum::typeid, 0 );
eb->DefineField( "value__", int::typeid, static_cast<FieldAttributes>(FieldAttributes::Private | FieldAttributes::SpecialName) );
FieldBuilder^ fb = eb->DefineField( "Field1", eb, static_cast<FieldAttributes>(FieldAttributes::Public | FieldAttributes::Literal | FieldAttributes::Static) );
fb->SetConstant( 1 );
enumType = eb;
// Comment out this field.
// When this field is defined, the loader cannot determine the size
// of the type. Therefore, a TypeResolve event is generated when the
// nested type is completed.
tb->DefineField( "Field2", eb, FieldAttributes::Public );
tNesting = tb->CreateType();
if ( tNesting == nullptr )
Console::WriteLine( "NestingType CreateType failed but didn't throw!" );
try
{
tNested = eb->CreateType();
if ( tNested == nullptr )
Console::WriteLine( "NestedType CreateType failed but didn't throw!" );
}
catch ( Exception^ )
{
// This is needed because you might have already completed the type in the TypeResolve event.
}
if ( tNested != nullptr )
{
Type^ x = tNested->DeclaringType;
if ( x == nullptr )
Console::WriteLine( "Declaring type is null." );
else
Console::WriteLine( x->Name );
}
asmBuild->Save( "NestedEnum.dll" );
// Remove the listener for the type resolve events.
currentDomain->TypeResolve -= resolveHandler;
}
};
Assembly^ TypeResolveHandler::ResolveEvent( Object^ sender, ResolveEventArgs^ args )
{
Console::WriteLine( args->Name );
// Use args.Name to look up the type name. In this case, you are getting AnEnum.
try
{
NestedEnum::tNested = NestedEnum::enumType->CreateType();
}
catch ( Exception^ )
{
// This is needed to throw away InvalidOperationException.
// Loader might send the TypeResolve event more than once
// and the type might be complete already.
}
// Complete the type.
return m_Module->Assembly;
}
int main()
{
NestedEnum::Main();
}
using System;
using System.Reflection;
using System.Reflection.Emit;
using System.Threading;
using System.Text;
using System.Resources;
using System.Collections;
using System.IO;
internal class NestedEnum {
internal static TypeBuilder enumType = null;
internal static Type tNested = null;
internal static Type tNesting = null;
public static void Main(String[] args) {
AssemblyName asmName = new AssemblyName();
asmName.Name = "NestedEnum";
AssemblyBuilder asmBuild = Thread.GetDomain().DefineDynamicAssembly(asmName, AssemblyBuilderAccess.RunAndSave);
ModuleBuilder modBuild = asmBuild.DefineDynamicModule("ModuleOne", "NestedEnum.dll");
// Hook up the event listening.
TypeResolveHandler typeResolveHandler = new TypeResolveHandler(modBuild);
// Add a listener for the type resolve events.
AppDomain currentDomain = Thread.GetDomain();
ResolveEventHandler resolveHandler = new ResolveEventHandler(typeResolveHandler.ResolveEvent);
currentDomain.TypeResolve += resolveHandler;
TypeBuilder tb = modBuild.DefineType("AType", TypeAttributes.Public);
TypeBuilder eb = tb.DefineNestedType("AnEnum", TypeAttributes.NestedPublic | TypeAttributes.Sealed, typeof(Enum), null);
eb.DefineField("value__", typeof(int), FieldAttributes.Private | FieldAttributes.SpecialName);
FieldBuilder fb = eb.DefineField("Field1", eb, FieldAttributes.Public | FieldAttributes.Literal | FieldAttributes.Static);
fb.SetConstant(1);
enumType = eb;
// Comment out this field.
// When this field is defined, the loader cannot determine the size
// of the type. Therefore, a TypeResolve event is generated when the
// nested type is completed.
tb.DefineField("Field2", eb, FieldAttributes.Public);
tNesting = tb.CreateType();
if (tNesting == null)
Console.WriteLine("NestingType CreateType failed but didn't throw!");
try {
tNested = eb.CreateType();
if (tNested == null)
Console.WriteLine("NestedType CreateType failed but didn't throw!");
}
catch {
// This is needed because you might have already completed the type in the TypeResolve event.
}
if (tNested != null) {
Type x = tNested.DeclaringType;
if (x == null)
Console.WriteLine("Declaring type was null.");
else
Console.WriteLine(x.Name);
}
asmBuild.Save( "NestedEnum.dll" );
// Remove the listener for the type resolve events.
currentDomain.TypeResolve -= resolveHandler;
}
}
// Helper class called when a resolve type event is raised.
internal class TypeResolveHandler
{
private Module m_Module;
public TypeResolveHandler(Module mod)
{
m_Module = mod;
}
public Assembly ResolveEvent(Object sender, ResolveEventArgs args)
{
Console.WriteLine(args.Name);
// Use args.Name to look up the type name. In this case, you are getting AnEnum.
try {
NestedEnum.tNested = NestedEnum.enumType.CreateType();
}
catch {
// This is needed to throw away InvalidOperationException.
// Loader might send the TypeResolve event more than once
// and the type might be complete already.
}
// Complete the type.
return m_Module.Assembly;
}
}
Imports System.Reflection
Imports System.Reflection.Emit
Imports System.Threading
Imports System.Text
Imports System.Resources
Imports System.Collections
Imports System.IO
Friend Class NestedEnum
Friend Shared enumType As TypeBuilder = Nothing
Friend Shared tNested As Type = Nothing
Friend Shared tNesting As Type = Nothing
Public Shared Sub Main()
Dim asmName As New AssemblyName()
asmName.Name = "NestedEnum"
Dim asmBuild As AssemblyBuilder = Thread.GetDomain().DefineDynamicAssembly(asmName, AssemblyBuilderAccess.RunAndSave)
Dim modBuild As ModuleBuilder = asmBuild.DefineDynamicModule("ModuleOne", "NestedEnum.dll")
' Hook up the event listening.
Dim typeResolveHandler As New TypeResolveHandler(modBuild)
' Add a listener for the type resolve events.
Dim currentDomain As AppDomain = Thread.GetDomain()
Dim resolveHandler As ResolveEventHandler = AddressOf typeResolveHandler.ResolveEvent
AddHandler currentDomain.TypeResolve, resolveHandler
Dim tb As TypeBuilder = modBuild.DefineType("AType", TypeAttributes.Public)
Dim eb As TypeBuilder = tb.DefineNestedType("AnEnum", TypeAttributes.NestedPublic Or TypeAttributes.Sealed, GetType([Enum]))
eb.DefineField("value__", GetType(Integer), FieldAttributes.Private Or FieldAttributes.SpecialName)
Dim fb As FieldBuilder = eb.DefineField("Field1", eb, FieldAttributes.Public Or FieldAttributes.Literal Or FieldAttributes.Static)
fb.SetConstant(1)
enumType = eb
' Comment out this field.
' When this field is defined, the loader cannot determine the size
' of the type. Therefore, a TypeResolve event is generated when the
' nested type is completed.
tb.DefineField("Field2", eb, FieldAttributes.Public)
tNesting = tb.CreateType()
If tNesting Is Nothing Then
Console.WriteLine("NestingType CreateType failed but didn't throw!")
End If
Try
tNested = eb.CreateType()
If tNested Is Nothing Then
Console.WriteLine("NestedType CreateType failed but didn't throw!")
End If
Catch
End Try ' This is needed because you might have already completed the type in the TypeResolve event.
If Not (tNested Is Nothing) Then
Dim x As Type = tNested.DeclaringType
If x Is Nothing Then
Console.WriteLine("Declaring type is Nothing.")
Else
Console.WriteLine(x.Name)
End If
End If
asmBuild.Save("NestedEnum.dll")
' Remove the listener for the type resolve events.
RemoveHandler currentDomain.TypeResolve, resolveHandler
End Sub
End Class
' Helper class called when a resolve type event is raised.
Friend Class TypeResolveHandler
Private m_Module As [Module]
Public Sub New([mod] As [Module])
m_Module = [mod]
End Sub
Public Function ResolveEvent(sender As [Object], args As ResolveEventArgs) As [Assembly]
Console.WriteLine(args.Name)
' Use args.Name to look up the type name. In this case, you are getting AnEnum.
Try
NestedEnum.tNested = NestedEnum.enumType.CreateType()
Catch
End Try ' This is needed to throw away InvalidOperationException.
' Loader might send the TypeResolve event more than once
' and the type might be complete already.
' Complete the type.
Return m_Module.Assembly
End Function 'ResolveEvent
End Class
Uwagi
Jeśli ten typ jest typem zagnieżdżonym, CreateType należy wywołać metodę dla otaczającego typu, zanim zostanie wywołana w typie zagnieżdżonym.
Jeśli bieżący typ pochodzi z niekompletnego typu lub implementuje niekompletne interfejsy, wywołaj metodę CreateType dla typu nadrzędnego i typów interfejsu przed wywołaniem go w bieżącym typie.
Jeśli typ otaczającego zawiera pole, które jest typem wartości zdefiniowanym jako typ zagnieżdżony (na przykład pole, które jest wyliczeniem zdefiniowanym jako typ zagnieżdżony), wywołanie CreateType metody dla otaczającego typu spowoduje wygenerowanie AppDomain.TypeResolve zdarzenia. Dzieje się tak, ponieważ moduł ładujący nie może określić rozmiaru otaczającego typu, dopóki zagnieżdżony typ nie zostanie ukończony. Obiekt wywołujący powinien zdefiniować procedurę obsługi dla TypeResolve zdarzenia, aby ukończyć definicję typu zagnieżdżonego przez wywołanie CreateType obiektu TypeBuilder reprezentującego typ zagnieżdżony. Przykładowy kod dla tego tematu przedstawia sposób definiowania takiego programu obsługi zdarzeń.
Typ jest tworzony tylko raz, niezależnie od tego, ile razy jest wywoływana CreateType metoda. Wszystkie wywołania zwracają ten sam Type obiekt.