Aracılığıyla paylaş


Koleksiyonlar (Visual Basic)

Birçok uygulama için ilgili nesne gruplarını oluşturmak ve yönetmek istiyorsunuz. Nesneleri gruplandırmanın iki yolu vardır: nesne dizileri oluşturarak ve nesne koleksiyonları oluşturarak.

Diziler en çok sabit sayıda kesin türü belirlenmiş nesne oluşturmak ve bunlarla çalışmak için kullanışlıdır. Diziler hakkında bilgi için bkz . Diziler.

Koleksiyonlar, nesne gruplarıyla çalışmak için daha esnek bir yol sağlar. Dizilerden farklı olarak, birlikte çalıştığınız nesne grubu, uygulamanın gereksinimleri değiştikçe dinamik olarak büyüyebilir ve küçülebilir. Bazı koleksiyonlar için, anahtarı kullanarak nesneyi hızla alabilmeniz için koleksiyona eklediğiniz herhangi bir nesneye anahtar atayabilirsiniz.

Koleksiyon bir sınıf olduğundan, bu koleksiyona öğe ekleyebilmek için önce sınıfın bir örneğini bildirmeniz gerekir.

Koleksiyonunuz yalnızca bir veri türünde öğeler içeriyorsa, ad alanındaki System.Collections.Generic sınıflardan birini kullanabilirsiniz. Genel bir koleksiyon, başka bir veri türünün eklenebilmesi için tür güvenliğini zorlar. Bir öğeyi genel bir koleksiyondan aldığınızda, veri türünü belirlemeniz veya dönüştürmeniz gerekmez.

Not

Bu konudaki örnekler için ve System.Linq ad alanları için System.Collections.Generic imports deyimlerini içerir.

Basit Koleksiyon Kullanma

Bu bölümdeki örnekler, kesin olarak belirlenmiş bir nesne listesiyle çalışmanızı sağlayan genel List<T> sınıfını kullanır.

Aşağıdaki örnek bir dize listesi oluşturur ve her biri için... kullanarak dizeler arasında yinelenir. Sonraki deyim.

' Create a list of strings.
Dim salmons As New List(Of String)
salmons.Add("chinook")
salmons.Add("coho")
salmons.Add("pink")
salmons.Add("sockeye")

' Iterate through the list.
For Each salmon As String In salmons
    Console.Write(salmon & " ")
Next
'Output: chinook coho pink sockeye

Bir koleksiyonun içeriği önceden biliniyorsa, koleksiyonu başlatmak için bir koleksiyon başlatıcısı kullanabilirsiniz. Daha fazla bilgi için bkz . Koleksiyon Başlatıcıları.

Koleksiyona öğe eklemek için bir koleksiyon başlatıcının kullanılması dışında, aşağıdaki örnek önceki örnekle aynıdır.

' Create a list of strings by using a
' collection initializer.
Dim salmons As New List(Of String) From
    {"chinook", "coho", "pink", "sockeye"}

For Each salmon As String In salmons
    Console.Write(salmon & " ")
Next
'Output: chinook coho pink sockeye

Bir For... Bir koleksiyonda yinelemek için bir For Each deyim yerine sonraki deyim. Bunu, dizin konumuna göre koleksiyon öğelerine erişerek gerçekleştirirsiniz. Öğelerin dizini 0'da başlar ve öğe sayısı eksi 1'de biter.

Aşağıdaki örnek yerine kullanarak For…NextFor Eachbir koleksiyonun öğelerinde yinelenir.

Dim salmons As New List(Of String) From
    {"chinook", "coho", "pink", "sockeye"}

For index = 0 To salmons.Count - 1
    Console.Write(salmons(index) & " ")
Next
'Output: chinook coho pink sockeye

Aşağıdaki örnek, kaldırılacak nesneyi belirterek bir öğeyi koleksiyondan kaldırır.

' Create a list of strings by using a
' collection initializer.
Dim salmons As New List(Of String) From
    {"chinook", "coho", "pink", "sockeye"}

' Remove an element in the list by specifying
' the object.
salmons.Remove("coho")

For Each salmon As String In salmons
    Console.Write(salmon & " ")
Next
'Output: chinook pink sockeye

Aşağıdaki örnek, öğeleri genel bir listeden kaldırır. For deyimi yerineFor Each... Azalan sırada yineleyen sonraki deyim kullanılır. Bunun nedeni, yöntemin RemoveAt kaldırılan bir öğeden sonraki öğelerin daha düşük bir dizin değerine sahip olmasına neden olmasıdır.

Dim numbers As New List(Of Integer) From
    {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}

' Remove odd numbers.
For index As Integer = numbers.Count - 1 To 0 Step -1
    If numbers(index) Mod 2 = 1 Then
        ' Remove the element by specifying
        ' the zero-based index in the list.
        numbers.RemoveAt(index)
    End If
Next

' Iterate through the list.
' A lambda expression is placed in the ForEach method
' of the List(T) object.
numbers.ForEach(
    Sub(number) Console.Write(number & " "))
' Output: 0 2 4 6 8

içindeki List<T>öğelerin türü için kendi sınıfınızı da tanımlayabilirsiniz. Aşağıdaki örnekte, Galaxy tarafından List<T> kullanılan sınıfı kodda tanımlanır.

Private Sub IterateThroughList()
    Dim theGalaxies As New List(Of Galaxy) From
        {
            New Galaxy With {.Name = "Tadpole", .MegaLightYears = 400},
            New Galaxy With {.Name = "Pinwheel", .MegaLightYears = 25},
            New Galaxy With {.Name = "Milky Way", .MegaLightYears = 0},
            New Galaxy With {.Name = "Andromeda", .MegaLightYears = 3}
        }

    For Each theGalaxy In theGalaxies
        With theGalaxy
            Console.WriteLine(.Name & "  " & .MegaLightYears)
        End With
    Next

    ' Output:
    '  Tadpole  400
    '  Pinwheel  25
    '  Milky Way  0
    '  Andromeda  3
End Sub

Public Class Galaxy
    Public Property Name As String
    Public Property MegaLightYears As Integer
End Class

Koleksiyon Türleri

Birçok yaygın koleksiyon .NET Framework tarafından sağlanır. Her koleksiyon türü belirli bir amaç için tasarlanmıştır.

Yaygın koleksiyon sınıflarından bazıları şu bölümde açıklanmıştır:

System.Collections.Generic Sınıfları

Ad alanında sınıflardan System.Collections.Generic birini kullanarak genel bir koleksiyon oluşturabilirsiniz. Genel koleksiyon, koleksiyondaki her öğe aynı veri türüne sahip olduğunda kullanışlıdır. Genel koleksiyon, yalnızca istenen veri türünün eklenmesine izin vererek güçlü yazma uygular.

Aşağıdaki tabloda ad alanının sık kullanılan sınıflarından bazıları listelenmektedir System.Collections.Generic :

Sınıf Açıklama
Dictionary<TKey,TValue> Anahtara göre düzenlenmiş bir anahtar/değer çifti koleksiyonunu temsil eder.
List<T> Dizin tarafından erişilebilen nesnelerin listesini temsil eder. Listeleri aramak, sıralamak ve değiştirmek için yöntemler sağlar.
Queue<T> Nesnelerin ilk gelen, ilk çıkan (FIFO) koleksiyonunu temsil eder.
SortedList<TKey,TValue> İlişkili IComparer<T> uygulamaya göre anahtara göre sıralanan anahtar/değer çiftleri koleksiyonunu temsil eder.
Stack<T> Nesnelerin son gelen, ilk çıkan (LIFO) koleksiyonunu temsil eder.

Ek bilgi için bkz . Yaygın Kullanılan Koleksiyon Türleri, Koleksiyon Sınıfı Seçme ve System.Collections.Generic.

System.Collections.Concurrent Sınıfları

.NET Framework 4 veya daha yeni sürümlerde, ad alanı içindeki System.Collections.Concurrent koleksiyonlar, birden çok iş parçacığından koleksiyon öğelerine erişmek için verimli iş parçacığı güvenli işlemler sağlar.

Birden çok iş parçacığı koleksiyona System.Collections.Concurrent eş zamanlı olarak eriştiğinde ad alanı içindeki System.Collections.Generic ve System.Collections ad alanlarına karşılık gelen türler yerine sınıflar kullanılmalıdır. Daha fazla bilgi için bkz. İş Parçacığı Kasa Koleksiyonları ve System.Collections.Concurrent.

Ad alanına dahil edilen System.Collections.Concurrent bazı sınıflar , ConcurrentDictionary<TKey,TValue>, ConcurrentQueue<T>ve ConcurrentStack<T>sınıflarıdırBlockingCollection<T>.

System.Collections Sınıfları

Ad alanındaki System.Collections sınıflar, öğeleri özel olarak yazılan nesneler olarak değil, türünde Objectnesneler olarak depolar.

Mümkün olduğunda, ad alanında eski türler System.Collections yerine ad alanında System.Collections.Generic veya System.Collections.Concurrent ad alanında genel koleksiyonları kullanmanız gerekir.

Aşağıdaki tabloda ad alanında sık kullanılan sınıflardan bazıları listelenmektedir System.Collections :

Sınıf Açıklama
ArrayList Boyutu gerektiği gibi dinamik olarak artan bir nesne dizisini temsil eder.
Hashtable Anahtarın karma koduna göre düzenlenmiş bir anahtar/değer çiftleri koleksiyonunu temsil eder.
Queue Nesnelerin ilk gelen, ilk çıkan (FIFO) koleksiyonunu temsil eder.
Stack Nesnelerin son gelen, ilk çıkan (LIFO) koleksiyonunu temsil eder.

Ad System.Collections.Specialized alanı, yalnızca dize koleksiyonları, bağlı liste ve karma sözlükler gibi özel ve kesin olarak belirlenmiş koleksiyon sınıfları sağlar.

Visual Basic Koleksiyon Sınıfı

Sayısal dizin veya anahtar kullanarak bir koleksiyon öğesine erişmek için Visual Basic Collection sınıfını String kullanabilirsiniz. Bir anahtar belirterek veya belirtmeden koleksiyon nesnesine öğe ekleyebilirsiniz. Anahtarı olmayan bir öğe eklerseniz, öğeye erişmek için sayısal dizinini kullanmanız gerekir.

Visual Basic Collection sınıfı tüm öğelerini türü Objectolarak depolar, böylece herhangi bir veri türünde öğe ekleyebilirsiniz. Uygunsuz veri türlerinin eklenmesine karşı bir koruma yoktur.

Visual Basic Collection sınıfını kullandığınızda, koleksiyondaki ilk öğe 1 dizinine sahiptir. Bu, başlangıç dizininin 0 olduğu .NET Framework koleksiyon sınıflarından farklıdır.

Mümkün olduğunda, Visual Basic Collection sınıfı yerine ad alanında System.Collections.Generic veya System.Collections.Concurrent ad alanında genel koleksiyonları kullanmanız gerekir.

Daha fazla bilgi için bkz. Collection.

Anahtar/Değer Çiftleri Koleksiyonu Uygulama

Genel Dictionary<TKey,TValue> koleksiyon, her öğenin anahtarını kullanarak bir koleksiyondaki öğelere erişmenizi sağlar. Sözlüğe yapılan her ekleme bir değerden ve ilişkili anahtarından oluşur. Sınıfı karma tablo olarak uygulandığından, bir değeri anahtarını kullanarak almak hızlıdır Dictionary .

Aşağıdaki örnek bir Dictionary koleksiyon oluşturur ve deyimini kullanarak For Each sözlükte yinelenir.

Private Sub IterateThroughDictionary()
    Dim elements As Dictionary(Of String, Element) = BuildDictionary()

    For Each kvp As KeyValuePair(Of String, Element) In elements
        Dim theElement As Element = kvp.Value

        Console.WriteLine("key: " & kvp.Key)
        With theElement
            Console.WriteLine("values: " & .Symbol & " " &
                .Name & " " & .AtomicNumber)
        End With
    Next
End Sub

Private Function BuildDictionary() As Dictionary(Of String, Element)
    Dim elements As New Dictionary(Of String, Element)

    AddToDictionary(elements, "K", "Potassium", 19)
    AddToDictionary(elements, "Ca", "Calcium", 20)
    AddToDictionary(elements, "Sc", "Scandium", 21)
    AddToDictionary(elements, "Ti", "Titanium", 22)

    Return elements
End Function

Private Sub AddToDictionary(ByVal elements As Dictionary(Of String, Element),
ByVal symbol As String, ByVal name As String, ByVal atomicNumber As Integer)
    Dim theElement As New Element

    theElement.Symbol = symbol
    theElement.Name = name
    theElement.AtomicNumber = atomicNumber

    elements.Add(Key:=theElement.Symbol, value:=theElement)
End Sub

Public Class Element
    Public Property Symbol As String
    Public Property Name As String
    Public Property AtomicNumber As Integer
End Class

Bunun yerine koleksiyonu derlemek Dictionary için bir koleksiyon başlatıcı kullanmak için ve AddToDictionary yöntemlerini aşağıdaki yöntemle değiştirebilirsinizBuildDictionary.

Private Function BuildDictionary2() As Dictionary(Of String, Element)
    Return New Dictionary(Of String, Element) From
        {
            {"K", New Element With
                {.Symbol = "K", .Name = "Potassium", .AtomicNumber = 19}},
            {"Ca", New Element With
                {.Symbol = "Ca", .Name = "Calcium", .AtomicNumber = 20}},
            {"Sc", New Element With
                {.Symbol = "Sc", .Name = "Scandium", .AtomicNumber = 21}},
            {"Ti", New Element With
                {.Symbol = "Ti", .Name = "Titanium", .AtomicNumber = 22}}
        }
End Function

Aşağıdaki örnek, bir öğeyi anahtara ContainsKey göre hızlı bir şekilde bulmak için yöntemini ve Item[] özelliğini Dictionary kullanır. özelliği, Item Visual Basic'teki kodu kullanarak koleksiyondaki elements bir öğeye elements(symbol) erişmenizi sağlar.

Private Sub FindInDictionary(ByVal symbol As String)
    Dim elements As Dictionary(Of String, Element) = BuildDictionary()

    If elements.ContainsKey(symbol) = False Then
        Console.WriteLine(symbol & " not found")
    Else
        Dim theElement = elements(symbol)
        Console.WriteLine("found: " & theElement.Name)
    End If
End Sub

Aşağıdaki örnek bunun yerine bir öğeyi anahtara TryGetValue göre hızla bulma yöntemini kullanır.

Private Sub FindInDictionary2(ByVal symbol As String)
    Dim elements As Dictionary(Of String, Element) = BuildDictionary()

    Dim theElement As Element = Nothing
    If elements.TryGetValue(symbol, theElement) = False Then
        Console.WriteLine(symbol & " not found")
    Else
        Console.WriteLine("found: " & theElement.Name)
    End If
End Sub

Koleksiyona Erişmek için LINQ Kullanma

LINQ (DilLe Tümleşik Sorgu) koleksiyonlara erişmek için kullanılabilir. LINQ sorguları filtreleme, sıralama ve gruplandırma özellikleri sağlar. Daha fazla bilgi için bkz . Visual Basic'te LINQ kullanmaya başlama.

Aşağıdaki örnekte genel Listbir üzerinde LINQ sorgusu çalıştırılır. LINQ sorgusu sonuçları içeren farklı bir koleksiyon döndürür.

Private Sub ShowLINQ()
    Dim elements As List(Of Element) = BuildList()

    ' LINQ Query.
    Dim subset = From theElement In elements
                  Where theElement.AtomicNumber < 22
                  Order By theElement.Name

    For Each theElement In subset
        Console.WriteLine(theElement.Name & " " & theElement.AtomicNumber)
    Next

    ' Output:
    '  Calcium 20
    '  Potassium 19
    '  Scandium 21
End Sub

Private Function BuildList() As List(Of Element)
    Return New List(Of Element) From
        {
            {New Element With
                {.Symbol = "K", .Name = "Potassium", .AtomicNumber = 19}},
            {New Element With
                {.Symbol = "Ca", .Name = "Calcium", .AtomicNumber = 20}},
            {New Element With
                {.Symbol = "Sc", .Name = "Scandium", .AtomicNumber = 21}},
            {New Element With
                {.Symbol = "Ti", .Name = "Titanium", .AtomicNumber = 22}}
        }
End Function

Public Class Element
    Public Property Symbol As String
    Public Property Name As String
    Public Property AtomicNumber As Integer
End Class

Koleksiyonu Sıralama

Aşağıdaki örnekte bir koleksiyonu sıralama yordamı gösterilmektedir. Örnek, sınıfında depolanan List<T>örneklerini Car sıralar. Car sınıfı, yönteminin IComparable<T> uygulanmasını gerektiren arabirimini CompareTo uygular.

yöntemine yapılan CompareTo her çağrı, sıralama için kullanılan tek bir karşılaştırma yapar. yönteminde CompareTo kullanıcı tarafından yazılan kod, geçerli nesnenin başka bir nesneyle her karşılaştırması için bir değer döndürür. Döndürülen değer, geçerli nesne diğer nesneden küçükse sıfırdan küçük, geçerli nesne diğer nesneden büyükse sıfırdan büyük ve eşitse sıfırdan büyük olur. Bu, kodda büyüktür, küçüktür ve eşittir ölçütlerini tanımlamanızı sağlar.

yönteminde ListCarscars.Sort() deyimi listeyi sıralar. yöntemine yapılan Sort bu çağrı, yönteminin List<T>CompareTo içindeki nesneler için Car otomatik olarak çağrılmalarına Listneden olur.

Public Sub ListCars()

    ' Create some new cars.
    Dim cars As New List(Of Car) From
    {
        New Car With {.Name = "car1", .Color = "blue", .Speed = 20},
        New Car With {.Name = "car2", .Color = "red", .Speed = 50},
        New Car With {.Name = "car3", .Color = "green", .Speed = 10},
        New Car With {.Name = "car4", .Color = "blue", .Speed = 50},
        New Car With {.Name = "car5", .Color = "blue", .Speed = 30},
        New Car With {.Name = "car6", .Color = "red", .Speed = 60},
        New Car With {.Name = "car7", .Color = "green", .Speed = 50}
    }

    ' Sort the cars by color alphabetically, and then by speed
    ' in descending order.
    cars.Sort()

    ' View all of the cars.
    For Each thisCar As Car In cars
        Console.Write(thisCar.Color.PadRight(5) & " ")
        Console.Write(thisCar.Speed.ToString & " ")
        Console.Write(thisCar.Name)
        Console.WriteLine()
    Next

    ' Output:
    '  blue  50 car4
    '  blue  30 car5
    '  blue  20 car1
    '  green 50 car7
    '  green 10 car3
    '  red   60 car6
    '  red   50 car2
End Sub

Public Class Car
    Implements IComparable(Of Car)

    Public Property Name As String
    Public Property Speed As Integer
    Public Property Color As String

    Public Function CompareTo(ByVal other As Car) As Integer _
        Implements System.IComparable(Of Car).CompareTo
        ' A call to this method makes a single comparison that is
        ' used for sorting.

        ' Determine the relative order of the objects being compared.
        ' Sort by color alphabetically, and then by speed in
        ' descending order.

        ' Compare the colors.
        Dim compare As Integer
        compare = String.Compare(Me.Color, other.Color, True)

        ' If the colors are the same, compare the speeds.
        If compare = 0 Then
            compare = Me.Speed.CompareTo(other.Speed)

            ' Use descending order for speed.
            compare = -compare
        End If

        Return compare
    End Function
End Class

Özel Koleksiyon Tanımlama

veya IEnumerable arabirimini IEnumerable<T> uygulayarak bir koleksiyon tanımlayabilirsiniz. Ek bilgi için bkz . Koleksiyon Numaralandırma.

Özel bir koleksiyon tanımlayabilmenize rağmen, bu konunun önceki bölümlerinde yer alan Koleksiyon Türleri bölümünde açıklanan .NET Framework'te yer alan koleksiyonları kullanmak genellikle daha iyidir.

Aşağıdaki örnek adlı AllColorsözel bir koleksiyon sınıfını tanımlar. Bu sınıf, yönteminin IEnumerable uygulanmasını gerektiren GetEnumerator arabirimini uygular.

yöntemi sınıfının GetEnumerator bir örneğini ColorEnumerator döndürür. ColorEnumeratorözelliğininMoveNext, yönteminin IEnumerator ve Reset yönteminin Current uygulanmasını gerektiren arabirimini uygular.

Public Sub ListColors()
    Dim colors As New AllColors()

    For Each theColor As Color In colors
        Console.Write(theColor.Name & " ")
    Next
    Console.WriteLine()
    ' Output: red blue green
End Sub

' Collection class.
Public Class AllColors
    Implements System.Collections.IEnumerable

    Private _colors() As Color =
    {
        New Color With {.Name = "red"},
        New Color With {.Name = "blue"},
        New Color With {.Name = "green"}
    }

    Public Function GetEnumerator() As System.Collections.IEnumerator _
        Implements System.Collections.IEnumerable.GetEnumerator

        Return New ColorEnumerator(_colors)

        ' Instead of creating a custom enumerator, you could
        ' use the GetEnumerator of the array.
        'Return _colors.GetEnumerator
    End Function

    ' Custom enumerator.
    Private Class ColorEnumerator
        Implements System.Collections.IEnumerator

        Private _colors() As Color
        Private _position As Integer = -1

        Public Sub New(ByVal colors() As Color)
            _colors = colors
        End Sub

        Public ReadOnly Property Current() As Object _
            Implements System.Collections.IEnumerator.Current
            Get
                Return _colors(_position)
            End Get
        End Property

        Public Function MoveNext() As Boolean _
            Implements System.Collections.IEnumerator.MoveNext
            _position += 1
            Return (_position < _colors.Length)
        End Function

        Public Sub Reset() Implements System.Collections.IEnumerator.Reset
            _position = -1
        End Sub
    End Class
End Class

' Element class.
Public Class Color
    Public Property Name As String
End Class

Yineleyiciler

Yineleyici, bir koleksiyon üzerinde özel yineleme gerçekleştirmek için kullanılır. Yineleyici bir yöntem veya get erişimci olabilir. Yineleyici, koleksiyonun her öğesini birer birer döndürmek için bir Yield deyimi kullanır.

Her İçin... kullanarak bir yineleyici çağırırsınız. Sonraki deyim. Döngünün For Each her yinelemesi yineleyiciyi çağırır. Yineleyicide bir Yield deyime ulaşıldığında, bir ifade döndürülür ve koddaki geçerli konum korunur. Yineleyici bir sonraki çağrılışında yürütme bu konumdan yeniden başlatılır.

Daha fazla bilgi için bkz . Yineleyiciler (Visual Basic).

Aşağıdaki örnekte yineleyici yöntemi kullanılır. Yineleyici yönteminin for... içinde bir deyimi vardırYield. Sonraki döngü. yönteminde ListEvenNumbers , deyim gövdesinin For Each her yinelemesi bir sonraki Yield deyime devam eden yineleyici yöntemine bir çağrı oluşturur.

Public Sub ListEvenNumbers()
    For Each number As Integer In EvenSequence(5, 18)
        Console.Write(number & " ")
    Next
    Console.WriteLine()
    ' Output: 6 8 10 12 14 16 18
End Sub

Private Iterator Function EvenSequence(
ByVal firstNumber As Integer, ByVal lastNumber As Integer) _
As IEnumerable(Of Integer)

' Yield even numbers in the range.
    For number = firstNumber To lastNumber
        If number Mod 2 = 0 Then
            Yield number
        End If
    Next
End Function

Ayrıca bkz.