UnsafeAccessorAttribute Clase
Definición
Importante
Parte de la información hace referencia a la versión preliminar del producto, que puede haberse modificado sustancialmente antes de lanzar la versión definitiva. Microsoft no otorga ninguna garantía, explícita o implícita, con respecto a la información proporcionada aquí.
Proporciona acceso a un miembro inaccesible de un 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
- Herencia
- Atributos
Ejemplos
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());
}
Comentarios
Puede aplicar este atributo a un extern static
método . El tiempo de ejecución proporcionará la implementación del extern static
método anotado con este atributo en función de la información del atributo y la firma del método al que se aplica el atributo. El tiempo de ejecución intentará encontrar el método o campo coincidente y reenviará la llamada a él. Si no se encuentra el método o campo coincidente, el cuerpo del extern static
método iniciará MissingFieldException o MissingMethodException.
Se admiten parámetros genéricos desde .NET 9. Los parámetros genéricos deben coincidir con el destino en el formulario y el índice (es decir, los parámetros de tipo deben ser parámetros de tipo y parámetros de método deben ser parámetros de método). Los extern static
parámetros genéricos del método también deben coincidir exactamente con las restricciones reflejadas en el destino. Si las restricciones no coinciden, el método produce InvalidProgramException.
Para Method, , FieldStaticMethody StaticField, el tipo del primer argumento del método anotado extern static
identifica el tipo propietario. Solo se examinará el tipo específico definido para los miembros inaccesibles. La jerarquía de tipos no se recorre buscando una coincidencia.
El valor del primer argumento se trata como this
puntero para los campos y métodos de instancia.
El primer argumento debe pasarse como ref
para los campos y métodos de instancia en estructuras.
La implementación static
de campos y métodos no usa el valor del primer argumento y puede ser null
.
El valor devuelto de un descriptor de acceso a un campo puede ser ref
si se desea establecer el campo.
Se puede acceder a los constructores mediante Constructor o Method.
El tipo de valor devuelto se considera para la coincidencia de firma. Los modreqs y los modopts no se consideran inicialmente para la coincidencia de firma. Sin embargo, si existe ambigüedad al omitir modreqs y modopts, se intenta una coincidencia precisa. Si todavía existe una ambigüedad, AmbiguousMatchException se produce .
De forma predeterminada, el nombre del método con atributos dicta el nombre del método o campo. Esto puede causar confusión en algunos casos, ya que las abstracciones del lenguaje, como las funciones locales de C#, generan nombres de IL desordenados. La solución a esto consiste en usar el nameof
mecanismo y definir la Name propiedad .
Constructores
UnsafeAccessorAttribute(UnsafeAccessorKind) |
Crea una instancia de que UnsafeAccessorAttribute proporciona acceso a un miembro de tipo UnsafeAccessorKind. |
Propiedades
Kind |
Obtiene el tipo de miembro al que se proporciona acceso. |
Name |
Obtiene o establece el nombre del miembro al que se proporciona acceso. |
TypeId |
Cuando se implementa en una clase derivada, obtiene un identificador único para este Attribute. (Heredado de Attribute) |
Métodos
Equals(Object) |
Devuelve un valor que indica si esta instancia es igual que un objeto especificado. (Heredado de Attribute) |
GetHashCode() |
Devuelve el código hash de esta instancia. (Heredado de Attribute) |
GetType() |
Obtiene el Type de la instancia actual. (Heredado de Object) |
IsDefaultAttribute() |
Si se reemplaza en una clase derivada, indica si el valor de esta instancia es el valor predeterminado de la clase derivada. (Heredado de Attribute) |
Match(Object) |
Cuando se invalida en una clase derivada, devuelve un valor que indica si esta instancia es igual a un objeto especificado. (Heredado de Attribute) |
MemberwiseClone() |
Crea una copia superficial del Object actual. (Heredado de Object) |
ToString() |
Devuelve una cadena que representa el objeto actual. (Heredado de Object) |
Se aplica a
Comentarios
https://aka.ms/ContentUserFeedback.
Próximamente: A lo largo de 2024 iremos eliminando gradualmente las Cuestiones de GitHub como mecanismo de retroalimentación para el contenido y lo sustituiremos por un nuevo sistema de retroalimentación. Para más información, consulta:Enviar y ver comentarios de