UnsafeAccessorAttribute Classe
Definição
Importante
Algumas informações se referem a produtos de pré-lançamento que podem ser substancialmente modificados antes do lançamento. A Microsoft não oferece garantias, expressas ou implícitas, das informações aqui fornecidas.
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
- 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) |