Penting
Roslyn/Source Generator saat ini memiliki keterbatasan dalam mengakses anggota pribadi proyek yang direferensikan. Selain itu, mengakses anggota pribadi dapat menyebabkan situasi di mana ia berfungsi dengan baik di IDE tetapi gagal selama proses pembangunan. Untuk lebih jelasnya, silakan lihat masalah Roslyn, MetadataImportOptions.Semua tidak berfungsi di generator sumber?. Untuk menghindari kebingungan, saya akan mengarsipkannya sampai hubungan antara Source Generator dan anggota pribadi membaik.
Source Generator dan .NET 8 UnsafeAccessor berbasiskan pengakses pribadi berperforma tinggi yang diketik dengan kuat untuk pengujian unit dan waktu proses.
[GeneratePrivateProxy(typeof(TargetType))]
menghasilkan proksi pengakses.
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 ;
Kode yang dihasilkan diketik sepenuhnya, Anda dapat mengakses file pribadi melalui IntelliSense dan ketika bidang pribadi diubah, dapat memeriksa kesalahan kompiler.
ref
, out
, in
, dan ref readonly
readonly
ref
Misalnya, ini adalah sampel struct dan static, ref return, dan konstruktor yang dapat diubah.
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 ) ;
Pustaka ini didistribusikan melalui NuGet, persyaratan minimumnya adalah .NET 8 dan C# 12.
PM> Instal-Paket PrivateProxy
Paket hanya menyediakan penganalisa dan kode yang dihasilkan tidak bergantung pada perpustakaan lain.
GeneratePrivateProxy
jenis dan anggota targetPrivateProxy
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 ) { }
}
Tipe proxy dapat berupa class
=> class
atau 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 memiliki dua konstruktor, ketika menggunakan parameter PrivateProxyGenerateKinds
, dapat mengkonfigurasi jenis anggota yang dihasilkan.
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 ,
}
Saat ini, fitur berikut tidak didukung
String
)Perpustakaan ini dilisensikan di bawah Lisensi MIT.