UnsafeAccessorAttribute Classe
Definição
Importante
Algumas informações dizem respeito a um produto pré-lançado que pode ser substancialmente modificado antes de ser lançado. A Microsoft não faz garantias, de forma expressa ou implícita, em relação à informação aqui apresentada.
Dá 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());
}
Observações
Podes aplicar este atributo a um extern static método. A implementação do extern static método anotado com este atributo será fornecida pelo runtime com base na informação do atributo e na assinatura do método ao qual o atributo é aplicado. O runtime tentará encontrar o método ou campo correspondente e encaminhará a chamada para ele. Se o método ou campo de correspondência não for encontrado, o corpo do extern static método irá lançar MissingFieldException ou MissingMethodException.
Parâmetros genéricos são suportados desde o .NET 9. Os parâmetros genéricos devem corresponder ao destino em forma e índice (ou seja, os parâmetros de tipo devem ser parâmetros de tipo e os parâmetros de método devem ser parâmetros de método). Os extern static parâmetros genéricos do método também devem corresponder exatamente a quaisquer restrições refletidas no alvo. Se as restrições não coincidirem, o método lança InvalidProgramException.
Para Method, StaticMethod, Field, e StaticField, o tipo do primeiro argumento do método anotado extern static identifica o tipo proprietário. Apenas o tipo específico definido será examinado para identificar membros inacessíveis. A hierarquia de tipos não é percorrida à procura de uma correspondência.
O valor do primeiro argumento é tratado como this ponteiro para campos de instância e métodos.
O primeiro argumento deve ser passado como ref para campos e métodos de exemplo 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 de retorno para um acessório a um campo deve ser passado como ref.
Os construtores podem ser acedidos usando Constructor ou Method.
Uma correspondência é determinada comparando assinaturas de metadados conforme definido na secção II.23.2 do ECMA-335. O tipo de retorno é considerado para o combate de assinatura. Os modreqs e modopts inicialmente não são considerados para a correspondência de assinatura. No entanto, se existir uma ambiguidade ignorando modreqs e modopts, tenta-se uma correspondência precisa. Se ainda existir ambiguidade, AmbiguousMatchException é lançado.
Por defeito, o nome do método atribuído dita o nome do método/campo. Isto pode causar confusão em alguns casos, pois abstrações de linguagem, como funções locais em C#, geram nomes IL distorcidos. A solução para isto é usar o nameof mecanismo e definir a Name propriedade.
Construtores
| Name | Description |
|---|---|
| UnsafeAccessorAttribute(UnsafeAccessorKind) |
Instância e UnsafeAccessorAttribute fornece acesso a um membro do mesmo UnsafeAccessorKindgénero. |
Propriedades
| Name | Description |
|---|---|
| Kind |
Obtém o tipo de membro a quem é dado acesso. |
| Name |
Obtém ou define o nome do membro ao qual é fornecido o acesso. |
| TypeId |
Quando implementado numa classe derivada, obtém um identificador único para esta Attribute. (Herdado de Attribute) |
Métodos
| Name | Description |
|---|---|
| Equals(Object) |
Devolve um valor que indica se esta instância é igual a um objeto especificado. (Herdado de Attribute) |
| GetHashCode() |
Devolve o código de hash para esta instância. (Herdado de Attribute) |
| GetType() |
Obtém o Type da instância atual. (Herdado de Object) |
| IsDefaultAttribute() |
Quando sobrescrito numa classe derivada, indica se o valor desta instância é o valor padrão para a classe derivada. (Herdado de Attribute) |
| Match(Object) |
Quando sobrescrito numa classe derivada, devolve um valor que indica se esta instância é igual a um objeto especificado. (Herdado de Attribute) |
| MemberwiseClone() |
Cria uma cópia superficial do atual Object. (Herdado de Object) |
| ToString() |
Devolve uma cadeia que representa o objeto atual. (Herdado de Object) |