중요한
현재 Roslyn/Source Generator에는 참조 프로젝트의 비공개 멤버에 액세스하는 데 제한이 있습니다. 또한 비공개 멤버에 액세스하면 IDE에서는 제대로 작동하지만 빌드 프로세스 중에는 실패하는 상황이 발생할 수 있습니다. 자세한 내용은 Roslyn 문제인 MetadataImportOptions.All이 소스 생성기에서 작동하지 않습니까?를 참조하세요. 혼란을 피하기 위해 Source Generators와 Private Members 간의 관계가 개선될 때까지 보관해 두겠습니다.
단위 테스트 및 런타임을 위한 소스 생성기 및 .NET 8 UnsafeAccessor 기반 고성능 강력한 유형의 개인 접근자입니다.
[GeneratePrivateProxy(typeof(TargetType))]
접근자 프록시를 생성합니다.
using PrivateProxy ;
public class Sample
{
int _field1 ;
int PrivateAdd ( int x , int y ) => x + y ;
}
[ GeneratePrivateProxy ( typeof ( Sample ) ) ]
public partial struct SampleProxy ;
// Source Generator generate this type
partial struct SampleProxy ( Sample target )
{
[ UnsafeAccessor ( UnsafeAccessorKind . Field , Name = " _field1 " ) ]
static extern ref int ___field1__ ( Sample target ) ;
[ UnsafeAccessor ( UnsafeAccessorKind . Method , Name = " PrivateAdd " ) ]
static extern int __PrivateAdd__ ( Sample target , int x , int y ) ;
public ref int _field1 => ref ___field1__ ( target ) ;
public int PrivateAdd ( int x , int y ) => __PrivateAdd__ ( target , x , y ) ;
}
public static class SamplePrivateProxyExtensions
{
public static SampleProxy AsPrivateProxy ( this Sample target )
{
return new SampleProxy ( target ) ;
}
}
// You can access like this.
var sample = new Sample ( ) ;
sample . AsPrivateProxy ( ) . _field1 = 10 ;
생성된 코드는 완전히 형식화되어 IntelliSense를 통해 프라이빗 필드에 액세스할 수 있으며 프라이빗 필드가 변경되면 컴파일러 오류를 확인할 수 있습니다.
ref
, out
, in
및 ref readonly
메서드 매개변수 지원readonly
필드 및 속성 지원ref
반환 지원예를 들어 이것은 변경 가능한 구조체와 정적, 참조 반환 및 생성자 샘플입니다.
using PrivateProxy ;
public struct MutableStructSample
{
int _counter ;
void Increment ( ) => _counter ++ ;
// static and ref sample
static ref int GetInstanceCounter ( ref MutableStructSample sample ) => ref sample . _counter ;
// constructor sample
MutalbeStructSample ( int x , int y ) { /* ... */ }
}
// use ref partial struct
[ GeneratePrivateProxy ( typeof ( MutableStructSample ) ) ]
public ref partial struct MutableStructSampleProxy ;
var sample = new MutableStructSample ( ) ;
var proxy = sample . AsPrivateProxy ( ) ;
proxy . Increment ( ) ;
proxy . Increment ( ) ;
proxy . Increment ( ) ;
// call private static method.
ref var counter = ref MutableStructSampleProxy . GetInstanceCounter ( ref sample ) ;
Console . WriteLine ( counter ) ; // 3
counter = 9999 ;
Console . WriteLine ( proxy . _counter ) ; // 9999
// call private constructor and create instance.
var sample = MutableStructSampleProxy . CreateMutableStructFromConstructor ( 111 , 222 ) ;
이 라이브러리는 NuGet을 통해 배포되며 최소 요구 사항은 .NET 8 및 C# 12입니다.
PM> 설치 패키지 PrivateProxy
패키지는 분석기만 제공하며 생성된 코드는 다른 라이브러리에 종속되지 않습니다.
GeneratePrivateProxy
대상 유형 및 멤버
public class /* struct */ SupportTarget
{
// field
private int field ;
private readonly int readOnlyField ;
// property
private int Property { get ; set ; }
private int GetOnlyProperty { get ; }
public int GetOnlyPrivateProperty { private get ; set ; }
public int SetOnlyPrivateProperty { get ; private set ; }
private int SetOnlyProperty { set => field = value ; }
private ref int RefGetOnlyProperty => ref field ;
private ref readonly int RefReadOnlyGetOnlyProperty => ref field ;
// method
private void VoidMethod ( ) { }
private int ReturnMethod ( ) => field ;
private int ParameterMethod ( int x , int y ) => x + y ;
private void RefOutInMethod ( in int x , ref int y , out int z , ref readonly int xyz ) { z = field ; }
private ref int RefReturnMethod ( ) => ref field ;
private ref readonly int RefReadOnlyReturnMethod ( ) => ref field ;
// static
static int staticField ;
static readonly int staticReadOnlyField ;
static int StaticProperty { get ; set ; }
static int StaticGetOnlyProperty { get ; }
public static int StaticGetOnlyPrivateProperty { private get ; set ; }
public static int StaticSetOnlyPrivateProperty { get ; private set ; }
private static int StaticSetOnlyProperty { set => staticField = value ; }
private static ref int StaticRefGetOnlyProperty => ref staticField ;
private static ref readonly int StaticRefReadOnlyGetOnlyProperty => ref staticField ;
private static void StaticVoidMethod ( ) { }
static int StaticReturnMethod ( ) => staticField ;
static int StaticParameterMethod ( int x , int y ) => x + y ;
static void StaticRefOutInMethod ( in int x , ref int y , out int z , ref readonly int xyz ) { z = staticField ; }
static ref int StaticRefReturnMethod ( ) => ref staticField ;
static ref readonly int StaticRefReadOnlyReturnMethod ( ) => ref staticField ;
static ref int StaticRefReturnMethodParameter ( ) => ref staticField ;
// constructor
SupportTarget ( ) { }
SupportTarget ( int x , int y ) { }
}
프록시 유형은 class
=> class
또는 struct
, struct
=> ref struct
일 수 있습니다.
using PrivateProxy ;
public class Sample ;
// class proxy type both supports class and struct(recommend is struct)
[ GeneratePrivateProxy ( typeof ( Sample ) ) ]
public partial class SampleProxy1 ;
[ GeneratePrivateProxy ( typeof ( Sample ) ) ]
public partial struct SampleProxy2 ;
public struct SamplleStruct ;
// struct only supports ref struct(when use standard struct, analyzer shows error)
[ GeneratePrivateProxy ( typeof ( SamplleStruct ) ) ]
public ref partial struct SamplleStructProxy ;
GeneratePrivateProxyAttribute에는 두 개의 생성자가 있으며 PrivateProxyGenerateKinds
매개 변수를 사용할 때 생성 멤버 종류를 구성할 수 있습니다.
public GeneratePrivateProxyAttribute ( Type target ) // use PrivateProxyGenerateKinds.All
public GeneratePrivateProxyAttribute ( Type target , PrivateProxyGenerateKinds generateKinds )
[ Flags ]
internal enum PrivateProxyGenerateKinds
{
All = 0 , // Field | Method | Property | Instance | Static | Constructor
Field = 1 ,
Method = 2 ,
Property = 4 ,
Instance = 8 ,
Static = 16 ,
Constructor = 32 ,
}
현재 다음 기능은 지원되지 않습니다
String
)이 라이브러리는 MIT 라이선스에 따라 라이선스가 부여됩니다.