สำคัญ
Roslyn/Source Generator ปัจจุบันมีข้อจำกัดในการเข้าถึงสมาชิกส่วนตัวของโปรเจ็กต์ที่อ้างอิง นอกจากนี้ การเข้าถึงสมาชิกส่วนตัวอาจนำไปสู่สถานการณ์ที่ทำงานได้ดีใน IDE แต่ล้มเหลวในระหว่างกระบวนการสร้าง สำหรับรายละเอียดเพิ่มเติม โปรดดูที่ปัญหาของ Roslyn MetadataImportOptions.All ไม่ทำงานในโปรแกรมสร้างต้นทางใช่หรือไม่ เพื่อหลีกเลี่ยงความสับสน ฉันจะเก็บถาวรสิ่งนี้จนกว่าความสัมพันธ์ระหว่าง Source Generators และสมาชิกส่วนตัวจะดีขึ้น
Source Generator และ .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