Desen tabanlı fixed
deyimiPattern-based fixed
statement
ÖzetSummary
Türlerin deyimlere katılmasını sağlayacak bir model ortaya çıkarabilir fixed
.Introduce a pattern that would allow types to participate in fixed
statements.
MotivasyonMotivation
Dil, yönetilen verileri sabitleme ve temel alınan arabelleğe yerel bir işaretçi alma mekanizması sağlar.The language provides a mechanism for pinning managed data and obtain a native pointer to the underlying buffer.
fixed(byte* ptr = byteArray)
{
// ptr is a native pointer to the first element of the array
// byteArray is protected from being moved/collected by the GC for the duration of this block
}
' De katılabilen türlerin kümesi, fixed
dizilerle ve bunlarla sınırlandırılmıştır System.String
.The set of types that can participate in fixed
is hardcoded and limited to arrays and System.String
. "Özel" türler, gibi yeni temel öğeler ImmutableArray<T>
Span<T>
Utf8String
tanıtıldığında ölçeklenmez.Hardcoding "special" types does not scale when new primitives such as ImmutableArray<T>
, Span<T>
, Utf8String
are introduced.
Ayrıca, için geçerli çözüm System.String
bir oldukça rigıd API 'sine dayanır.In addition, the current solution for System.String
relies on a fairly rigid API. API 'nin şekli, System.String
UTF16 kodlu verileri nesne başlığından sabit bir uzaklığa katıştıran bitişik bir nesne olduğunu gösterir.The shape of the API implies that System.String
is a contiguous object that embeds UTF16 encoded data at a fixed offset from the object header. Bu yaklaşım, temeldeki düzende değişiklik gerektirebilecek çeşitli tekliflerde sorun bulmuştur.Such approach has been found problematic in several proposals that could require changes to the underlying layout. System.String
Yönetilmeyen birlikte çalışma amacıyla kendi iç gösteriminden daha esnek bir şekilde geçiş yapabilmesi istenebilir.It would be desirable to be able to switch to something more flexible that decouples System.String
object from its internal representation for the purpose of unmanaged interop.
Ayrıntılı tasarımDetailed design
DesenPattern
Uygun bir model tabanlı "fixed" gereksinimi şunlar için gereklidir:A viable pattern-based “fixed” need to:
- Örneği sabitlemek için yönetilen başvuruları sağlayın ve işaretçiyi başlatın (tercihen bu aynı başvurudur)Provide the managed references to pin the instance and to initialize the pointer (preferably this is the same reference)
- Yönetilmeyen öğenin türünü ("String" için "Char") kesin bir şekilde iletinConvey unambiguously the type of the unmanaged element (i.e. “char” for “string”)
- Başvurabileceğiniz bir şey olmadığında "boş" durumunda davranış göstermelidir.Prescribe the behavior in "empty" case when there is nothing to refer to.
- API yazarları, türü dışında kullanımını engelleyen tasarım kararlarına doğru göndermemelidir
fixed
.Should not push API authors toward design decisions that hurt the use of the type outside offixed
.
Yukarıdaki bir başvuru döndüren üyenin tanınması için yukarıdaki ref [readonly] T GetPinnableReference()
I think the above could be satisfied by recognizing a specially named ref-returning member: ref [readonly] T GetPinnableReference()
.
Deyimin kullanılabilmesi için fixed
aşağıdaki koşulların karşılanması gerekir:In order to be used by the fixed
statement the following conditions must be met:
- Bir tür için yalnızca bir tane belirtilen üye vardır.There is only one such member provided for a type.
- Veya ile
ref
döndürürref readonly
.Returns byref
orref readonly
. (readonly
sabit/salt okunur türlerin yazarları, türü, güvenli kodda kullanılabilen YAZıLABILIR API eklemeden uygulayabilir)(readonly
is permitted so that authors of immutable/readonly types could implement the pattern without adding writeable API that could be used in safe code) - T, yönetilmeyen bir türdür.T is an unmanaged type.
(çünkü
T*
işaretçi türü olur.(sinceT*
becomes the pointer type. Kısıtlama, "yönetilmeyen" kavramı genişletilmişse doğal olarak genişletilir.The restriction will naturally expand if/when the notion of "unmanaged" is expanded) nullptr
Sabitlemeye veri olmadığında, büyük olasılıkla empest 'yi almanın mümkün olduğu durumlarda yönetilen döndürür.Returns managednullptr
when there is no data to pin – probably the cheapest way to convey emptiness. (dizeler null sonlandırıldığı için "" dizesinin ' \ 0 ' öğesine bir başvuru döndürdüğünü unutmayın)(note that “” string returns a ref to '\0' since strings are null-terminated)
Bunun için alternatif olarak, #3
boş durumlarda sonucun tanımsız veya uygulamaya özgü olması için izin verebilir.Alternatively for the #3
we can allow the result in empty cases be undefined or implementation-specific. Bununla birlikte, API 'nin daha tehlikeli ve uygunsuz uyumluluk ve istenmeyen uyumlulukta olması olabilir.That, however, may make the API more dangerous and prone to abuse and unintended compatibility burdens.
ÇeviriTranslation
fixed(byte* ptr = thing)
{
// <BODY>
}
Aşağıdaki sözde kod olur (C# ' ta ifade edilemez)becomes the following pseudocode (not all expressible in C#)
byte* ptr;
// specially decorated "pinned" IL local slot, not visible to user code.
pinned ref byte _pinned;
try
{
// NOTE: null check is omitted for value types
// NOTE: `thing` is evaluated only once (temporary is introduced if necessary)
if (thing != null)
{
// obtain and "pin" the reference
_pinned = ref thing.GetPinnableReference();
// unsafe cast in IL
ptr = (byte*)_pinned;
}
else
{
ptr = default(byte*);
}
// <BODY>
}
finally // finally can be omitted when not observable
{
// "unpin" the object
_pinned = nullptr;
}
BulunmaktadırDrawbacks
- GetPinnableReference yalnızca içinde kullanılmak üzere tasarlanmıştır
fixed
, ancak güvenli kodda kullanımını hiçbir şey engellemez, bu yüzden uygulayıcıyı göz önünde bulundurmanız gerekir.GetPinnableReference is intended to be used only infixed
, but nothing prevents its use in safe code, so implementor must keep that in mind.
AlternatiflerAlternatives
Kullanıcılar GetPinnableReference veya benzeri bir üyeyi ortaya çıkarabilir ve bunu şu şekilde kullanabilirUsers can introduce GetPinnableReference or similar member and use it as
fixed(byte* ptr = thing.GetPinnableReference())
{
// <BODY>
}
Alternatif çözüm isteniyorsa, için çözüm yoktur System.String
.There is no solution for System.String
if alternative solution is desired.
Çözümlenmemiş sorularUnresolved questions
- [] "Boş" durumundaki davranış.[ ] Behavior in "empty" state. -
nullptr
orundefined
? -nullptr
orundefined
? - [] Uzantı yöntemleri göz önünde bulundurulmalıdır mi?[ ] Should the extension methods be considered ?
- [] Üzerinde bir model algılanırsa
System.String
, bunun yerine mi kazanamalıdır?[ ] If a pattern is detected onSystem.String
, should it win over ?
Tasarım toplantılarıDesign meetings
Henüz yok.None yet.