Partilhar via


UnsafeAccessorAttribute Classe

Definição

Fornece acesso a um membro inacessível de um tipo específico.

public ref class UnsafeAccessorAttribute sealed : Attribute
[System.AttributeUsage(System.AttributeTargets.Method, AllowMultiple=false, Inherited=false)]
public sealed class UnsafeAccessorAttribute : Attribute
[<System.AttributeUsage(System.AttributeTargets.Method, AllowMultiple=false, Inherited=false)>]
type UnsafeAccessorAttribute = class
    inherit Attribute
Public NotInheritable Class UnsafeAccessorAttribute
Inherits Attribute
Herança
UnsafeAccessorAttribute
Atributos

Exemplos

public class Class
{
    static void StaticPrivateMethod() { }
    static int StaticPrivateField;
    Class(int i) { PrivateField = i; }
    void PrivateMethod() { }
    int PrivateField;
    int PrivateProperty { get => PrivateField; }
}

public void CallStaticPrivateMethod()
{
    StaticPrivateMethod(null);

    [UnsafeAccessor(UnsafeAccessorKind.StaticMethod, Name = nameof(StaticPrivateMethod))]
    extern static void StaticPrivateMethod(Class c);
}
public void GetSetStaticPrivateField()
{
    ref int f = ref GetSetStaticPrivateField(null);

    [UnsafeAccessor(UnsafeAccessorKind.StaticField, Name = "StaticPrivateField")]
    extern static ref int GetSetStaticPrivateField(Class c);
}
public void CallPrivateConstructor()
{
    Class c1 = PrivateCtor(1);

    Class c2 = (Class)RuntimeHelpers.GetUninitializedObject(typeof(Class));

    PrivateCtorAsMethod(c2, 2);

    [UnsafeAccessor(UnsafeAccessorKind.Constructor)]
    extern static Class PrivateCtor(int i);

    [UnsafeAccessor(UnsafeAccessorKind.Method, Name = ".ctor")]
    extern static void PrivateCtorAsMethod(Class c, int i);

}
public void CallPrivateMethod(Class c)
{
    PrivateMethod(c);

    [UnsafeAccessor(UnsafeAccessorKind.Method, Name = nameof(PrivateMethod))]
    extern static void PrivateMethod(Class c);
}
public void GetPrivateProperty(Class c)
{
    int f = GetPrivateProperty(c);

    [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "get_PrivateProperty")]
    extern static int GetPrivateProperty(Class c);
}
public void GetSetPrivateField(Class c)
{
    ref int f = ref GetSetPrivateField(c);

    [UnsafeAccessor(UnsafeAccessorKind.Field, Name = "PrivateField")]
    extern static ref int GetSetPrivateField(Class c);
}

// Generic example
public class Class<T>
{
    private T _field;
    private void M(T t) { }
    private void GM<U>(U u) { }
    private void GMWithConstraints<U, V>(U u, V v) where U : V, IEquatable<U> { }
}

class Accessors<V>
{
    [UnsafeAccessor(UnsafeAccessorKind.Field, Name = "_field")]
    public extern static ref V GetSetPrivateField(Class<V> c);

    [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "M")]
    public extern static void CallM(Class<V> c, V v);

    [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "GM")]
    public extern static void CallGM<X>(Class<V> c, X x);

    [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "GMWithConstraints")]
    public extern static void CallGMWithConstraints<X, Y>(Class<V> c, X x, Y y) where X : Y, IEquatable<X>;
}

public void AccessGenericType(Class<int> c)
{
    ref int f = ref Accessors<int>.GetSetPrivateField(c);

    Accessors<int>.CallM(c, 1);

    Accessors<int>.CallGM<string>(c, string.Empty);

    Accessors<int>.CallGMWithConstraints<string, object>(c, string.Empty, new object());
}

Comentários

Você pode aplicar esse atributo a um método extern static. A implementação do método extern static anotada com esse atributo será fornecida pelo runtime com base nas informações no atributo e na assinatura do método ao qual o atributo é aplicado. O runtime tentará localizar o método ou o campo correspondente e encaminhar a chamada para ele. Se o método ou campo correspondente não for encontrado, o corpo do método extern static gerará MissingFieldException ou MissingMethodException.

Há suporte para parâmetros genéricos desde o .NET 9. Parâmetros genéricos devem corresponder ao destino em formulário e índice (ou seja, parâmetros de tipo devem ser parâmetros de tipo e parâmetros de método devem ser parâmetros de método). Os parâmetros genéricos do método extern static também devem corresponder exatamente a quaisquer restrições refletidas no destino. Se as restrições não corresponderem, o método gerará InvalidProgramException.

Para Method, StaticMethod, Fielde StaticField, o tipo do primeiro argumento do método extern static anotado identifica o tipo proprietário. Somente o tipo específico definido será examinado para membros inacessíveis. A hierarquia de tipos não é andada à procura de uma correspondência.

O valor do primeiro argumento é tratado como this ponteiro para campos e métodos de instância.

O primeiro argumento deve ser passado como ref para campos e métodos de instância em structs.

O valor do primeiro argumento não é usado pela implementação para static campos e métodos e pode ser null.

O valor retornado de um acessador para um campo pode ser ref se a configuração do campo for desejada.

Construtores podem ser acessados usando Constructor ou Method.

Uma correspondência é determinada comparando assinaturas de metadados conforme definido na seção II.23.2 de ECMA-335. O tipo de retorno é considerado para a correspondência de assinatura. Modreqs e modopts inicialmente não são considerados para a correspondência de assinatura. No entanto, se houver uma ambiguidade ignorando modreqs e modopts, uma correspondência precisa será tentada. Se ainda existir uma ambiguidade, AmbiguousMatchException será gerada.

Por padrão, o nome do método atribuído determina o nome do método/campo. Isso pode causar confusão em alguns casos, pois abstrações de linguagem, como funções locais em C#, geram nomes il mutilados. A solução para isso é usar o mecanismo nameof e definir a propriedade Name.

Construtores

UnsafeAccessorAttribute(UnsafeAccessorKind)

Cria uma instância de um UnsafeAccessorAttribute fornecendo acesso a um membro do tipo UnsafeAccessorKind.

Propriedades

Kind

Obtém o tipo de membro ao qual o acesso é fornecido.

Name

Obtém ou define o nome do membro ao qual o acesso é fornecido.

TypeId

Quando implementado em uma classe derivada, obtém um identificador exclusivo para esse Attribute.

(Herdado de Attribute)

Métodos

Equals(Object)

Retorna um valor que indica se essa instância é igual a um objeto especificado.

(Herdado de Attribute)
GetHashCode()

Retorna o código hash dessa instância.

(Herdado de Attribute)
GetType()

Obtém o Type da instância atual.

(Herdado de Object)
IsDefaultAttribute()

Quando substituído em uma classe derivada, indica se o valor dessa instância é o valor padrão para a classe derivada.

(Herdado de Attribute)
Match(Object)

Quando substituído em uma classe derivada, retorna um valor que indica se essa instância é igual a um objeto especificado.

(Herdado de Attribute)
MemberwiseClone()

Cria uma cópia superficial do Objectatual.

(Herdado de Object)
ToString()

Retorna uma cadeia de caracteres que representa o objeto atual.

(Herdado de Object)

Aplica-se a