Bitişik bellek ile C ++ vektörünün C # eşdeğeri?


87

C ++ vektörünün C # eşdeğeri nedir?

Bu özelliği arıyorum:

Standart dizilere kıyasla erişim için performans cezası olmayan dinamik bir bitişik olarak depolanan bellek dizisine sahip olmak.

Ben arıyordum ve diyorlar ki .NET equivalent to the vector in C++ is the ArrayList:

ArrayList bu bitişik bellek özelliğine sahip mi?


4
CLR, bir yapının belleğe nasıl tahsis edileceğini belirlemeniz (veya hatta tutarlı bir şekilde beklemeniz) için metale yeterince yakın değil mi?
Aphex

Yanıtlar:


104

A kullanabilirsiniz List<T>ve Tbir değer türü olduğunda , bitişik belleğe tahsis edilecektir, Tbu bir başvuru türü ise durum böyle olmaz .

Misal:

List<int> integers = new List<int>();
integers.Add(1);
integers.Add(4);
integers.Add(7);

int someElement = integers[1];

2
@cMinor, List<T>sınıfın dokümantasyonu birçok örnek içeriyor ancak cevabımı bir tane içerecek şekilde güncelledim.
Darin Dimitrov

5
CLR'ye% 100 aşina değilim, ancak Tbir referans türü olsa bile hala bitişik belleğe sahip olacağınız mantıklı . Temelde bir dizi işaretçi ...
josaphatv

"eğer T bir referans türü ise durum böyle olmaz" - bu durum aynı T[]... OP "standart dizilere karşı erişim için performans cezası istemiyor " ve List<T>bunu sağlıyor. Ve eğer Tbir başvuru türü ise, bu T*C ++ 'ya benzer , böylece C ++' da olduğu kadar bitişiklik elde edersiniz. Nesnelerin kendilerinin bitişik olmasını istiyorsa, o zaman elbette değer türlerine ihtiyaç duyar ... her iki dilde de. Aradaki fark, elbette, C ++ 'da herhangi bir türün değer veya ref olarak kullanılabilmesidir, oysa C #' da sınıf / yapı ayrımı yoluyla türün bir özelliğidir.
Jim Balter

Bugün bir şey öğrendim. Her List<T>zaman dahili olarak bağlantılı bir liste olarak uygulandığını düşündüm . Öyleyse, biz çağırdığımızda dinamik olarak nasıl genişliyor Add()? Redim PreserveTüm diziyi yeni bir konuma kopyalamak için kullanılan VB6'lar gibi bir şey ?
dotNET

@dotNet, dahili olarak List<T>küçük bir dizi oluşturur T[]. İçerdeki öğeler diziye eklenir. Dizinin boyutu tamamlandığında, bir öncekinin iki katı büyüklükte yeni bir dizi oluşturulur. Veriler yeni büyük diziye kopyalanır, küçültülür, vb. Bir geliştirici doldurmadan önce yeterince büyük bir iç diziyi oluşturmak için .NET için bir ipucu verebilir List yapıcı yoluyla: new List<T>(expected_array_size).
Artru

16

kullanın List<T>. Dahili olarak dizileri kullanır ve diziler bitişik bellek kullanır.


2
Tamamen doğru değil. T bir referans türü ise, bitişik bellek olmayacaktır.
Matteo Mosca

2
@ Matteo Kaynağa bakarsanız, private T[] _items;arka uç depolaması için kullanılan, referans türü veya değil.
Bala R

13
Bunu biliyorum. Fakat bana söyle. Bir Listeniz var <SomeClass>. SomeClass örneklerine yapılan başvurular bitişik bellekte depolanır, ancak örneklerin kendileri depolanmaz. Referans türleri olarak, yığın içinde olacaklar ve yığının nasıl çalıştığını kesinlikle biliyorsunuz.
Matteo Mosca

@MatteoMosca referansları bitişik olarak depolamak, en azından bir düzeydeki indirimi ortadan kaldırır. Hiç yoktan iyidir sanırım.
Tim Seguine

7
@MatteoMosca OP, "standart dizilere karşı erişim için performans kesintisi" istemedi. Bu, T'nin ne olduğuna bakılmaksızın List <T> için geçerlidir, bu nedenle bu sayfadaki tüm yorumlarınız yanlıştır.
Jim Balter

16

Her şeyden önce, uzak durun Arraylistya Hashtable. Bu sınıflar, jenerikler lehine, kullanımdan kaldırılmış olarak kabul edilecektir. Hala eski amaçlar için dilde.

Şimdi, aradığınız şey List<T>sınıf. T bir değer türü ise, bitişik belleğe sahip olacağınızı, ancak T bir referans türü ise bariz nedenlerden ötürü olmayacağını unutmayın.


15

C # birçok başvuru türüne sahiptir. Bir konteyner referansları bitişik olarak depolasa bile , nesnelerin kendileri yığın boyunca dağılmış olabilir.


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.