Aracılığıyla paylaş


Sayısal IntPtr

Not

Bu makale bir özellik belirtimidir. Belirtim, özelliğin tasarım belgesi olarak görev alır. Önerilen belirtim değişikliklerini ve özelliğin tasarımı ve geliştirilmesi sırasında gereken bilgileri içerir. Bu makaleler, önerilen belirtim değişiklikleri son haline getirilene ve geçerli ECMA belirtimine dahil edilene kadar yayımlanır.

Özellik belirtimi ile tamamlanan uygulama arasında bazı tutarsızlıklar olabilir. Bu farklılıklar, ilgili dil tasarım toplantısı (LDM) notlarındakaydedilir.

Özellik belirtimlerini C# dil standardına benimseme işlemi hakkında daha fazla bilgi edinmek içinbelirtimleri makalesinde bulabilirsiniz.

Şampiyon sorunu: https://github.com/dotnet/csharplang/issues/6065

Özet

Bu, nint/ türlerinin nuintSystem.IntPtr/temel alınan türlerden farklı olduğu ilk yerel tamsayılar özelliğinde (System.UIntPtr) yapılan bir düzeltmedir. Kısacası, nint/nuintSystem.IntPtrile ilgili olarak / için yaptığımız gibi System.UIntPtrintSystem.Int32basit türler olarak ele alıyoruz. System.Runtime.CompilerServices.RuntimeFeature.NumericIntPtr çalışma zamanı özellik bayrağı bu yeni davranışı tetikler.

Tasarım

8.3.5 Basit türler

C# basit türler olarak adlandırılan önceden tanımlanmış struct türleri kümesi sağlar. Basit türler anahtar sözcükler aracılığıyla tanımlanır, ancak bu anahtar sözcükler yalnızca aşağıdaki tabloda açıklandığı gibi struct ad alanında önceden tanımlanmış System türleri için diğer adlardır.

Anahtar Sözcük Adlandırılmış tür
sbyte System.SByte
byte System.Byte
short System.Int16
ushort System.UInt16
int System.Int32
uint System.UInt32
nint System.IntPtr
nuint System.UIntPtr
long System.Int64
ulong System.UInt64
char System.Char
float System.Single
double System.Double
bool System.Boolean
decimal System.Decimal

[...]

8.3.6 Integral türleri

C# on bir integral türünü destekler: sbyte, byte, short, ushort, int, uint, nint, nuint, long, ulongve char. [...]

8.8 Yönetilmeyen türler

Başka bir deyişle, unmanaged_type aşağıdakilerden biridir:

  • sbyte, byte, short, ushort, int, uint, nint, nuint, long, ulong, char, float, double, decimalveya bool.
  • Herhangi bir enum_type.
  • Kullanıcı tanımlı, oluşturulmuş tür olmayan ve sadece unmanaged_typealanlarını içeren struct_type.
  • Güvenli olmayan kodda, herhangi bir pointer_tipiolabilir.

10.2.3 Örtük sayısal dönüştürmeler

Örtük sayısal dönüştürmeler şunlardır:

  • sbyte short, int, nint, long, float, doubleveya decimal.
  • byte 'den short, ushort, int, uint, nint, nuint, long, ulong, float, doubleveya decimal.
  • short'den int, nint, long, float, doubleveya decimal.
  • ushort, int, uint, ,nint, nuint,, long, ulong, float, doubleveya decimal.
  • int'dan nint'e, long'ye, float'e, double'e veya decimal'e.
  • uint'den nuint, long, ulong, float, doubleveya decimal.
  • , nint'den long, float, doubleveya decimal.
  • , nuint'den ulong, float, doubleveya decimal.
  • long'den float, doubleveya decimal.
  • ulong'den float, doubleveya decimal.
  • char 'den ushort, int, uint, nint, nuint, long, ulong, float, doubleveya decimal.
  • float'dan double'e

[...]

10.2.11 Örtük sabit ifade dönüştürmeleri

Örtük sabit ifade dönüştürmesi aşağıdaki dönüştürmelere izin verir:

  • türündeki bir int, sbyte değeri hedef türün aralığında olması koşuluyla byte, short, ushort, uint, nint, nuintveya türüne dönüştürülebilir. [...]

10.3.2 Açık sayısal dönüştürmeler

Açık sayısal dönüştürmeler, örtük sayısal dönüştürmenin henüz mevcut olmadığı bir numeric_type'den başka bir numeric_type'e yapılan dönüştürmelerdir.

  • sbyte'den byte, ushort, uint, nuint, ulongveya char.
  • byte ile sbyte veya char.
  • short sbyte, byte, ushort, uint, nuint, ulongveya char.
  • ushort'dan sbyte, byte, shortveya char.
  • int'den sbyte, byte, short, ushort, uint, nuint, ulongveya char.
  • uint sbyte, byte, short, ushort, int, nintveya char.
  • long 'den sbyte, byte, short, ushort, int, uint, nint, nuint, ulongveya char.
  • nint'den sbyte, byte, short, ushort, int, uint, nuint, ulongveya char.
  • nuint'den sbyte, byte, short, ushort, int, uint, nint, longveya char.
  • ulong 'den sbyte, byte, short, ushort, int, uint, nint, nuint, longveya char.
  • char'den sbyte, byteveya short.
  • float 'den sbyte, byte, short, ushort, int, uint, nint, nuint, long, ulong, charveya decimal.
  • double 'den sbyte, byte, short, ushort, int, uint, nint, nuint, long, ulong, char, floatveya decimal.
  • decimal 'den sbyte, byte, short, ushort, int, uint, nint, nuint, long, ulong, char, floatveya double.

[...]

10.3.3 Açık numaralandırma dönüştürmeleri

Açık numaralandırma dönüştürmeleri şunlardır:

  • sbyte, byte, short, ushort, int, uint, nint, nuint, long, ulong, char, float, doubleya da decimal herhangi bir enum_type.
  • herhangi bir enum_type, sbyte, byte, short, ushort, int, uint, nint, nuint, long, ulong, char, float, doubleveya decimal.
  • Herhangi bir enum_type'den herhangi bir diğer enum_type'e.

12.6.4.7 Daha iyi dönüştürme hedefi

T₁ ve T₂iki tür verildiğinde, aşağıdakilerden biri geçerli olduğunda, T₁'ye göre daha iyi bir dönüştürme hedefi olarak 'dır.

  • T₁'dan T₂'ye örtük dönüştürme mevcut ve T₂'dan T₁'e örtük dönüştürme yok
  • T₁, Task<S₁>'dir, T₂, Task<S₂>'dir ve S₁, S₂'ten daha iyi bir dönüştürme hedefidir.
  • T₁, S₁ imzalı bir tam sayı türü olduğunda S₁? veya S₁; ve T₂, S₂ işaretsiz bir integral türü olduğunda S₂? veya S₂'dır. Özellikle: [...]

12.8.12 Öğeye erişim

[...] argument_list ifade sayısı, array_typederecesiyle aynı olacaktır ve her ifade int, uint, nint, nuint, longveya ulong, türünde olmalıdır veya bu türlerden birine veya daha fazlasına örtük olarak dönüştürülebilir olmalıdır.

11.8.12.2 Dizi erişimi

[...] argument_list ifade sayısı, array_typederecesiyle aynı olacaktır ve her ifade int, uint, nint, nuint, longveya ulong, türünde olmalıdır veya bu türlerden birine veya daha fazlasına örtük olarak dönüştürülebilir olmalıdır.

[...] form P[A]bir dizi erişiminin çalışma zamanı işlemesi; burada P bir primary_no_array_creation_expression olan array_type ve A bir argument_listise aşağıdaki adımlardan oluşur: [...]

  • argument_list dizin ifadeleri soldan sağa doğru sırayla değerlendirilir. Her dizin ifadesinin değerlendirilmesinin ardından, aşağıdaki türlerden birine örtük bir dönüştürme gerçekleştirilir: int, uint, nint, nuint, long, ulong. Bu listede örtük dönüştürmenin bulunduğu ilk tür seçilir. [...]

12.8.16 Son ek artırma ve azaltma işleçleri

Belirli bir işleç uygulamasını seçmek için birli işleç aşırı yükleme çözümlemesi uygulanır. Önceden tanımlanmış ++ ve -- işleçleri şu türler için vardır: sbyte, byte, short, ushort, int, uint, nint, nuint,long, ulong, char, float, double, decimalve herhangi bir sabit listesi türü.

12.9.2 Tekli artı operatörü

Önceden tanımlanmış birli artı işleçleri şunlardır:

...
nint operator +(nint x);
nuint operator +(nuint x);

12.9.3 Tekil eksi işleci

Önceden tanımlanmış birli eksi işleçleri şunlardır:

  • Tamsayı olumsuzlaması:

    ...
    nint operator –(nint x);
    

12.8.16 Son ek artırma ve azaltma işleçleri

Aşağıdaki türler için önceden tanımlanmış ++ ve -- işleçleri vardır: sbyte, byte, short, ushort, int, uint, nint, nuint, long, ulong, char, float, double, decimalve herhangi bir sabit listesi türü.

11.7.19 Varsayılan değer ifadeleri

Ayrıca, tür şu değer türlerinden biriyse default_value_expression sabit bir ifadedir: sbyte, byte, short, ushort, int, uint, nint, nuint, long, ulong, char, float, double, decimal, bool, veya herhangi bir numaralandırma türü.

12.9.5 Bit düzeyinde tamamlama işleci

Önceden tanımlanmış bit düzeyinde tamamlayıcı işleçleri şunlardır:

...
nint operator ~(nint x);
nuint operator ~(nuint x);

12.9.6 Ön ek artırma ve azaltma işleçleri

Aşağıdaki türler için önceden tanımlanmış ++ ve -- işleçleri vardır: sbyte, byte, short, ushort, int, uint, nint, nuint, long, ulong, char, float, double, decimalve herhangi bir sabit listesi türü.

12.10 Aritmetik işleçler

12.10.2 Çarpma işleci

Önceden tanımlanmış çarpma işleçleri aşağıda listelenmiştir. Tüm işleçler birlikte x ve y'in çarpımını hesaplar.

  • Tamsayı çarpması:

    ...
    nint operator *(nint x, nint y);
    nuint operator *(nuint x, nuint y);
    

12.10.3 Bölme işleci

Önceden tanımlanmış bölme işleçleri aşağıda listelenmiştir. İşleçlerin tümü x ve ybölümlerini hesaplar.

  • Tamsayı bölme:

    ...
    nint operator /(nint x, nint y);
    nuint operator /(nuint x, nuint y);
    

12.10.4 Kalan işleci

Önceden tanımlanmış kalan operatörler aşağıda listelenmiştir. İşleçlerin tümü, x ile yarasındaki bölmenin geri kalanını hesaplar.

  • Kalan tamsayı:

    ...
    nint operator %(nint x, nint y);
    nuint operator %(nuint x, nuint y);
    

12.10.5 Toplama işleci

  • Tamsayı ekleme:

    ...
    nint operator +(nint x, nint y);
    nuint operator +(nuint x, nuint y);
    

12.10.6 Çıkarma işleci

  • Tamsayı çıkarma:

    ...
    nint operator –(nint x, nint y);
    nuint operator –(nuint x, nuint y);
    

12.11 Shift işleçleri

Önceden tanımlanmış vardiya işleçleri aşağıda listelenmiştir.

  • Sola kaydır:

    ...
    nint operator <<(nint x, int count);
    nuint operator <<(nuint x, int count);
    
  • Sağa kaydır:

    ...
    nint operator >>(nint x, int count);
    nuint operator >>(nuint x, int count);
    

    >> operatörü, aşağıda açıklandığı şekilde hesaplanan bir miktar bit kadar x'i sağa kaydırır.

    x inttüründe olduğunda, nint veya longdüşük sıralı x bitleri atılır, kalan bitler sağa kaydırılır ve x negatif değilse yüksek sıralı boş bit konumları sıfıra ayarlanır ve x negatifse bir olarak ayarlanır.

    x uinttüründe olduğunda, nuint veya ulong, düşük sıralı x bitleri atılır, kalan bitler sağa kaydırılır ve yüksek sıralı boş bit konumları sıfır olarak ayarlanır.

  • İşaretsiz sağa kaydırma:

    ...
    nint operator >>>(nint x, int count);
    nuint operator >>>(nuint x, int count);
    

Önceden tanımlanmış işleçler için kaydıracak bit sayısı şu şekilde hesaplanır: [...]

  • x türü nint veya nuintolduğunda, vardiya sayısı 32 bit platformda düşük sıralı beş bit count veya 64 bit platformda alt sıra altı bit count tarafından verilir.

12.12 İlişkisel ve tür testi işleçleri

12.12.2 Tamsayı karşılaştırma işleçleri

Önceden tanımlanmış tamsayı karşılaştırma işleçleri şunlardır:

...
bool operator ==(nint x, nint y);
bool operator ==(nuint x, nuint y);

bool operator !=(nint x, nint y);
bool operator !=(nuint x, nuint y);

bool operator <(nint x, nint y);
bool operator <(nuint x, nuint y);

bool operator >(nint x, nint y);
bool operator >(nuint x, nuint y);

bool operator <=(nint x, nint y);
bool operator <=(nuint x, nuint y);

bool operator >=(nint x, nint y);
bool operator >=(nuint x, nuint y);

12.12 Mantıksal işleçler

12.12.2 Tamsayı mantıksal işleçleri

Önceden tanımlanmış tamsayı mantıksal işleçleri şunlardır:

...
nint operator &(nint x, nint y);
nuint operator &(nuint x, nuint y);

nint operator |(nint x, nint y);
nuint operator |(nuint x, nuint y);

nint operator ^(nint x, nint y);
nuint operator ^(nuint x, nuint y);

12.22 Sabit ifadeler

Sabit ifade bir değer türü veya başvuru türü olabilir. Sabit ifade bir değer türüyse, şu türlerden biri olmalıdır: sbyte, byte, short, ushort, int, uint, nint, nuint, long, ulong, char, float, double, decimal, bool, veya herhangi bir numaralandırma türü.

[...]

Örtük sabit ifade dönüştürme, sabit ifadenin değeri hedef türün aralığında olması koşuluyla, int türünde bir sabit ifadenin sbyte, byte, short, ushort, uint, nint, nuint, veya ulongdönüştürülmesini sağlar.

17.4 Dizi öğesi erişimi

Dizi öğelerine, formunun A[I₁, I₂, ..., Iₓ] ifadeleri kullanılarak erişilir; burada A bir dizi türünün ifadesidir ve her Iₑint, uint, nint, nuint,long, ulongtüründe bir ifadedir veya örtük olarak bu türlerden birine veya birden fazlasına dönüştürülebilir. Dizi elemanı erişiminin sonucu, dizinler tarafından seçilen dizi elemanı olan bir değişkendir.

23.5 İşaretçi dönüştürmeleri

23.5.1 Genel

[...]

Ayrıca, güvenli olmayan bir bağlamda, kullanılabilir açık dönüştürmeler kümesi aşağıdaki açık işaretçi dönüştürmelerini içerecek şekilde genişletilir:

  • Herhangi bir pointer_type'dan herhangi bir diğer pointer_type'e.
  • sbyte, byte, short, ushort, int, uint, ,nint, nuint,,longveya ulong'dan herhangi birine pointer_type.
  • herhangi bir pointer_type, sbyte, byte, short, ushort, int, uint, nint, nuint,longveya ulong.

23.6.4 İşaretçi öğesi erişimi

[...] P[E]formun işaretçi öğesi erişiminde, Pvoid*dışında bir işaretçi türünün ifadesi ve E örtük olarak int, uint, nint, nuint,longveya ulongdönüştürülebilen bir ifade olmalıdır.

23.6.7 İşaretçi aritmetiği

Güvenli olmayan bir bağlamda, + işleci ve işleci void*dışındaki tüm işaretçi türlerinin değerlerine uygulanabilir. Bu nedenle, T*her işaretçi türü için aşağıdaki işleçler örtük olarak tanımlanır:

[...]
T* operator +(T* x, nint y);
T* operator +(T* x, nuint y);
T* operator +(nint x, T* y);
T* operator +(nuint x, T* y);
T* operator -(T* x, nint y);
T* operator -(T* x, nuint y);

Bir işaretçi türü P olan ifade T* ve türünde N ifadesi olan int, uint, nint, nuint,longveya ulongifadeleri verilen P + N ve N + P, T*tarafından belirtilen adrese N * sizeof(T) eklenmesiyle oluşan P türündeki işaretçi değerini hesaplar. Benzer şekilde, P – N ifadesi T*tarafından verilen adresten N * sizeof(T) çıkarılarak elde edilen P türündeki işaretçi değerini hesaplar.

Dikkat edilmesi gereken çeşitli noktalar

Hataya neden olan değişiklikler

Bu tasarımın ana etkilerinden biri, System.IntPtr ve System.UIntPtr'in bazı yerleşik operatörler (dönüştürmeler, tekil ve ikili) kazanmasıdır.
Bunlar checked işleçlerini içerir, bu da bu türlerdeki aşağıdaki işleçlerin taşma hatası vereceği anlamına gelir:

  • IntPtr + int
  • IntPtr - int
  • IntPtr -> int
  • long -> IntPtr
  • void* -> IntPtr

Meta veri kodlama

Bu tasarım, nint ve nuint'in System.IntPtrkullanılmadan System.UIntPtr ve System.Runtime.CompilerServices.NativeIntegerAttributeolarak yayılması anlamına gelir.
Benzer şekilde, meta veriler yüklenirken NativeIntegerAttribute yoksayılabilir.