다음을 통해 공유


UnsafeAccessorAttribute 클래스

정의

특정 형식의 액세스할 수 없는 멤버에 대한 액세스를 제공합니다.

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
상속
UnsafeAccessorAttribute
특성

예제

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());
}

설명

이 특성을 extern static 메서드에 적용할 수 있습니다. 이 특성으로 주석이 추가된 extern static 메서드의 구현은 특성의 정보 및 특성이 적용되는 메서드의 서명에 따라 런타임에서 제공됩니다. 런타임은 일치하는 메서드 또는 필드를 찾아 호출을 전달하려고 합니다. 일치하는 메서드나 필드를 찾을 수 없으면 extern static 메서드의 본문이 MissingFieldException 또는 MissingMethodExceptionthrow됩니다.

제네릭 매개 변수는 .NET 9부터 지원됩니다. 제네릭 매개 변수는 폼 및 인덱스로 대상과 일치해야 합니다. 즉, 형식 매개 변수는 형식 매개 변수여야 하고 메서드 매개 변수는 메서드 매개 변수여야 합니다. extern static 메서드의 제네릭 매개 변수도 대상에 반영된 제약 조건과 정확히 일치해야 합니다. 제약 조건이 일치하지 않으면 메서드는 InvalidProgramExceptionthrow합니다.

Method, StaticMethod, FieldStaticField주석이 추가된 extern static 메서드의 첫 번째 인수 형식은 소유 형식을 식별합니다. 정의된 특정 형식만 액세스할 수 없는 멤버에 대해 검사됩니다. 형식 계층 구조가 일치하는 항목을 찾지 않습니다.

첫 번째 인수의 값은 인스턴스 필드 및 메서드에 대한 this 포인터로 처리됩니다.

첫 번째 인수는 구조체의 인스턴스 필드 및 메서드에 대한 ref 전달되어야 합니다.

첫 번째 인수의 값은 static 필드 및 메서드에 대한 구현에서 사용되지 않으며 null수 있습니다.

필드 설정을 원하는 경우 필드에 대한 접근자의 반환 값을 ref 수 있습니다.

생성자는 Constructor 또는 Method사용하여 액세스할 수 있습니다.

일치는 ECMA-335II.23.2 섹션에 정의된 메타데이터 서명을 비교하여 결정됩니다. 반환 형식은 서명 일치에 대해 고려됩니다. Modreqs 및 modopts는 처음에 서명 일치에 대해 고려되지 않습니다. 그러나 modreqs 및 modopts를 무시하는 모호성이 있으면 정확한 일치가 시도됩니다. 모호성이 여전히 있으면 AmbiguousMatchException throw됩니다.

기본적으로 특성이 지정된 메서드의 이름은 메서드/필드의 이름을 지정합니다. C# 로컬 함수와 같은 언어 추상화가 IL 이름을 생성하기 때문에 이로 인해 혼동이 발생할 수 있습니다. 이에 대한 해결 방법은 nameof 메커니즘을 사용하고 Name 속성을 정의하는 것입니다.

생성자

UnsafeAccessorAttribute(UnsafeAccessorKind)

종류 UnsafeAccessorKind멤버에 대한 액세스를 제공하는 UnsafeAccessorAttribute 인스턴스화합니다.

속성

Kind

액세스가 제공되는 멤버의 종류를 가져옵니다.

Name

액세스가 제공되는 멤버의 이름을 가져오거나 설정합니다.

TypeId

파생 클래스에서 구현되는 경우 이 Attribute대한 고유 식별자를 가져옵니다.

(다음에서 상속됨 Attribute)

메서드

Equals(Object)

이 인스턴스가 지정된 개체와 같은지 여부를 나타내는 값을 반환합니다.

(다음에서 상속됨 Attribute)
GetHashCode()

이 인스턴스의 해시 코드를 반환합니다.

(다음에서 상속됨 Attribute)
GetType()

현재 인스턴스의 Type 가져옵니다.

(다음에서 상속됨 Object)
IsDefaultAttribute()

파생 클래스에서 재정의되는 경우 이 인스턴스의 값이 파생 클래스의 기본값인지 여부를 나타냅니다.

(다음에서 상속됨 Attribute)
Match(Object)

파생 클래스에서 재정의되는 경우 이 인스턴스가 지정된 개체와 같은지 여부를 나타내는 값을 반환합니다.

(다음에서 상속됨 Attribute)
MemberwiseClone()

현재 Object단순 복사본을 만듭니다.

(다음에서 상속됨 Object)
ToString()

현재 개체를 나타내는 문자열을 반환합니다.

(다음에서 상속됨 Object)

적용 대상