مهم
لدى Roslyn/Source Generator الحالي قيود في الوصول إلى الأعضاء الخاصين في المشاريع المشار إليها. علاوة على ذلك، يمكن أن يؤدي الوصول إلى الأعضاء الخاصين إلى مواقف حيث يعمل بشكل جيد في IDE ولكنه يفشل أثناء عملية الإنشاء. لمزيد من التفاصيل، يرجى الرجوع إلى مشكلة روزلين، MetadataImportOptions.All لا يعمل في مولدات المصدر؟. لتجنب الارتباك، سأقوم بأرشفة هذا حتى يتم تحسين العلاقة بين مولدات المصدر والأعضاء الخاصين.
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.