IsExplicitlyDereferenced 클래스

정의

관리되는 포인터가 메서드 서명 내의 포인터 매개 변수를 나타낸다는 것을 나타냅니다. 이 클래스는 상속할 수 없습니다.

public ref class IsExplicitlyDereferenced abstract sealed
public static class IsExplicitlyDereferenced
type IsExplicitlyDereferenced = class
Public Class IsExplicitlyDereferenced
상속
IsExplicitlyDereferenced

예제

다음 예제에서는 리플렉션을 사용하여 개체를 IsExplicitlyDereferenced 어셈블리로 내보내는 방법을 보여 줍니다.



#using <mscorlib.dll>

using namespace System;
using namespace System::Reflection;
using namespace System::Reflection::Emit;
using namespace System::Runtime::CompilerServices;
using namespace System::Threading;


ref class CodeEmitter
{
private:
    AssemblyBuilder^ asmBuilder;
    String^ asmName;
    ModuleBuilder^ modBuilder;


    void prepareAssembly(String^ name){
        
        // Check the input.
        if(!name){
        
            throw gcnew ArgumentNullException("AssemblyName");
        }

        asmName = name;

        // Create an AssemblyName object and set the name.
        AssemblyName^ asmName = gcnew AssemblyName();

        asmName->Name = name;

        // Use the AppDomain class to create an AssemblyBuilder instance.

        AppDomain^ currentDomain = Thread::GetDomain();

        asmBuilder = currentDomain->DefineDynamicAssembly(asmName,AssemblyBuilderAccess::RunAndSave);

        // Create a dynamic module.
        modBuilder = asmBuilder->DefineDynamicModule(name);
    }


public:

    // Constructor.
    CodeEmitter(String ^ AssemblyName){

        prepareAssembly(AssemblyName);
    }

    // Create a new type.
    TypeBuilder^ CreateType(String^ name){
       
        // Check the input.
        if(!name){
        
            throw gcnew ArgumentNullException("AssemblyName");
        }

        return modBuilder->DefineType( name );
    }

    // Write the assembly.
    void WriteAssembly(MethodBuilder^ entryPoint){
    
        // Check the input.
        if(!entryPoint){
        
            throw gcnew ArgumentNullException("entryPoint");
        }

        asmBuilder->SetEntryPoint( entryPoint );
        asmBuilder->Save( asmName );
    }

};

void main()
{

    // Create a CodeEmitter to handle assembly creation.
    CodeEmitter ^ e = gcnew CodeEmitter("program.exe");

    // Create a new type.
    TypeBuilder^ mainClass = e->CreateType("MainClass");
    
    // Create a new method.
    MethodBuilder^ mBuilder = mainClass->DefineMethod("mainMethod", MethodAttributes::Static);

    // Create an ILGenerator and emit IL for 
    // a simple "Hello World." program.
    ILGenerator^ ilGen = mBuilder->GetILGenerator();

    ilGen->Emit(OpCodes::Ldstr, "Hello World");

    array<Type^>^mType = {String::typeid};

    MethodInfo^ writeMI = Console::typeid->GetMethod( "WriteLine", mType );

    ilGen->EmitCall(OpCodes::Call, writeMI, nullptr );

    ilGen->Emit( OpCodes::Ret );

    /////////////////////////////////////////////////
    /////////////////////////////////////////////////
    // Apply a required custom modifier
    // to a field.
    /////////////////////////////////////////////////
    /////////////////////////////////////////////////

    array<Type^>^fType = {IsExplicitlyDereferenced::typeid};

    mainClass->DefineField("modifiedInteger", Type::GetType("System.IntPtr"), fType, nullptr, FieldAttributes::Private);

    // Create the type.
    mainClass->CreateType();

    // Write the assembly using a reference to 
    // the entry point.
    e->WriteAssembly(mBuilder);

    Console::WriteLine(L"Assembly created.");
}

설명

C++에서 관리되는 포인터 및 관리되는 참조는 메타데이터로 포인터로 내보내집니다. 메타데이터의 두 형식을 구분하기 위해 Microsoft C++ 컴파일러는 관리되는 포인터에 이 한정자를 적용합니다. 관리되는 참조 형식에는 한정자가 내보내지 않습니다. 컴파일러는 메타데이터 범위에서 메서드를 가져올 때 올바른 호출 구문을 알아야 합니다. 클래스와 해당 파트너인 IsExplicitlyDereferenced 클래스는 IsImplicitlyDereferenced 포인터 매개 변수에서 참조 매개 변수를 구분합니다.

컴파일러는 메타데이터 내에서 사용자 지정 한정자를 내보내 기본 동작이 적절하지 않을 때 JIT(Just-In-Time) 컴파일러가 값을 처리하는 방식을 변경합니다. JIT 컴파일러가 사용자 지정 한정자를 발견하면 한정자가 지정하는 방식으로 값을 처리합니다. 컴파일러는 메서드, 매개 변수 및 반환 값에 사용자 지정 한정자를 적용할 수 있습니다. JIT 컴파일러는 필수 한정자에 응답해야 하지만 선택적 한정자를 무시할 수 있습니다.

다음 기술 중 하나를 사용하여 메타데이터로 사용자 지정 한정자를 내보낼 수 있습니다.

적용 대상