Tanımlama Kümeleri (Visual Basic)

Visual Basic 2017'den başlayarak, Visual Basic dili tanımlama kümeleri oluşturma ve tanımlama grubu öğelerine erişmeyi kolaylaştıran tanımlama kümeleri için yerleşik destek sunar. Tanımlama grubu, belirli bir sayı ve değer dizisine sahip basit bir veri yapısıdır. Tanımlama grubu örneği oluştururken, her değerin (veya öğenin) sayısını ve veri türünü tanımlarsınız. Örneğin, 2 tanımlama grubu (veya çift) iki öğeye sahiptir. birincisi bir Boolean değer, ikincisi ise bir Stringolabilir. Tanımlama kümeleri birden çok değeri tek bir nesnede depolamayı kolaylaştırdığından, genellikle bir yöntemden birden çok değer döndürmek için basit bir yol olarak kullanılırlar.

Önemli

Tanımlama grubu desteği türü ValueTuple gerektirir. .NET Framework 4.7 yüklü değilse, NuGet Galerisi'nde bulunan NuGet paketini System.ValueTupleeklemeniz gerekir. Bu paket olmadan, "Önceden tanımlanmış 'ValueTuple(Of,,,)' türü tanımlanmadı veya içeri aktarılmadı" gibi bir derleme hatası alabilirsiniz.

Tanımlama grubu örneği oluşturma ve kullanma

Virgülle ayrılmış değerlerini parantez içine alarak bir tanımlama grubu örneği oluşturursunuz. Bu değerlerin her biri, tanımlama grubunun bir alanı haline gelir. Örneğin, aşağıdaki kod ilk değeri, ikinci değeri ve Boolean üçüncü değeri String olarak üç (veya 3 tanımlama grubu) Date tanımlar.

Dim holiday = (#07/04/2017#, "Independence Day", True)

Varsayılan olarak, bir tanımlama grubundaki her alanın adı, alanın tanımlama grubundaki tek tabanlı konumuyla birlikte dizeden Item oluşur. Bu 3 tanımlama grubu için, Date alanı şeklindedirItem1String, Boolean alan ise Item2şeklindedirItem3. Aşağıdaki örnek, önceki kod satırında örneği gösterilen tanımlama grubu alanlarının değerlerini görüntüler

Console.WriteLine($"{holiday.Item1} is {holiday.Item2}" +
                  $"{If(holiday.Item3, ", a national holiday", String.Empty)}")
' Output: 7/4/2017 12:00:00 AM Is Independence Day, a national holiday

Visual Basic tanımlama grubunun alanları okuma-yazmadır; bir tanımlama grubu örneği oluşturdunuzktan sonra, bu tanımlama kümesinin değerlerini değiştirebilirsiniz. Aşağıdaki örnek, önceki örnekte oluşturulan tanımlama grubundaki üç alandan ikisini değiştirir ve sonucu görüntüler.

holiday.Item1 = #01/01/2018#
holiday.Item2 = "New Year's Day"
Console.WriteLine($"{holiday.Item1} is {holiday.Item2}" +
                  $"{If(holiday.Item3, ", a national holiday", String.Empty)}")
' Output: 1/1/2018 12:00:00 AM Is New Year's Day, a national holiday

Adlandırılmış bir tanımlama grubu örneği oluşturma ve kullanma

Bir tanımlama grubu alanları için varsayılan adları kullanmak yerine, tanımlama grubu öğelerine kendi adlarınızı atayarak adlandırılmış bir tanımlama grubu örneği oluşturabilirsiniz. Ardından tanımlama grubu alanlarına atanan adlarıyla veya varsayılan adlarıyla erişilebilir. Aşağıdaki örnek, ilk alanı , ikinci Nameve üçüncü IsHolidayalanını EventDateaçıkça adlandırması dışında, daha önce olduğu gibi aynı 3 tanımlama grubu örneğini oluşturur. Ardından alan değerlerini görüntüler, değiştirir ve alan değerlerini yeniden görüntüler.

Dim holiday = (EventDate:=#07/04/2017#, Name:="Independence Day", IsHoliday:=True)
Console.WriteLine($"{holiday.EventDate} Is {holiday.Name}" +
                  $"{If(holiday.IsHoliday, ", a national holiday", String.Empty)}")
holiday.Item1 = #01/01/2018#
holiday.Item2 = "New Year's Day"
Console.WriteLine($"{holiday.Item1} is {holiday.Item2}" +
                  $"{If(holiday.Item3, ", a national holiday", String.Empty)}")
' The example displays the following output:
'   7/4/2017 12:00:00 AM Is Independence Day, a national holiday
'   1/1/2018 12:00:00 AM Is New Year's Day, a national holiday

Demet adlarını değişken, alan veya parametrenin tür bildiriminin bir parçası olarak da belirtebilirsiniz:

Dim holiday As (EventDate As Date, Name As String, IsHoliday As Boolean) =
    (#07/04/2017#, "Independence Day", True)
Console.WriteLine(holiday.Name)
' Output: Independence Day

veya bir yöntemin dönüş türünde.

Bu, özellikle bir koleksiyon başlatıcısına tanımlama kümeleri sağlarken kullanışlıdır; tanımlama grubu adları koleksiyonun tür bildiriminin bir parçası olarak sağlanabilir:

Dim events As New List(Of (EventDate As Date, Name As String, IsHoliday As Boolean)) From {
    (#07/04/2017#, "Independence Day", True),
    (#04/22/2017#, "Earth Day", False)
}
Console.WriteLine(events(1).IsHoliday)
' Output: False

Çıkarsanan demet öğe adları

Visual Basic 15.3'den başlayarak, Visual Basic tanımlama grubu öğelerinin adlarını çıkarsayabilir; bunları açıkça atamanız gerekmez. Bir dizi değişkenden bir tanımlama grubu başlatırken ve tanımlama grubu öğesi adının değişken adıyla aynı olmasını istediğinizde, çıkarılmış demet adları yararlıdır.

Aşağıdaki örnek, , ve capitalolmak üzere açıkça adlandırılmış üç öğe stateNamestateiçeren bir stateInfo tanımlama grubu oluşturur. Öğeleri adlandırdığınızda, tanımlama grubu başlatma deyiminin adlandırılmış öğeleri aynı adlı değişkenlerin değerlerini atadığını unutmayın.

Const state As String = "MI"
Const stateName As String = "Michigan"
Const capital As String = "Lansing"
Dim stateInfo = (state:=state, stateName:=stateName, capital:=capital)
Console.WriteLine($"{stateInfo.stateName}: 2-letter code: {stateInfo.state}, Capital {stateInfo.capital}")
' The example displays the following output:
'      Michigan: 2-letter code: MI, Capital Lansing

Öğeler ve değişkenler aynı ada sahip olduğundan, Visual Basic derleyicisi aşağıdaki örnekte gösterildiği gibi alanların adlarını çıkarabilir.

Const state As String = "MI"
Const stateName As String = "Michigan"
Const capital As String = "Lansing"
Dim stateInfo = (state, stateName, capital)
Console.WriteLine($"{stateInfo.stateName}: 2-letter code: {stateInfo.State}, Capital {stateInfo.capital}")
' The example displays the following output:
'      Michigan: 2-letter code: MI, Capital Lansing

Çıkarsanan tanımlama grubu öğe adlarını etkinleştirmek için, Visual Basic projesi (*.vbproj) dosyanızda kullanılacak Visual Basic derleyicisinin sürümünü tanımlamanız gerekir:

<PropertyGroup>
  <LangVersion>15.3</LangVersion>
</PropertyGroup>

Sürüm numarası, Visual Basic derleyicisinin 15.3 sürümünden itibaren herhangi bir sürümü olabilir. Belirli bir derleyici sürümünü sabit kodlamak yerine, "En Son" değerini, sisteminizde yüklü Olan Visual Basic derleyicisinin en son sürümüyle derlenecek değer LangVersion olarak da belirtebilirsiniz.

Daha fazla bilgi için bkz . Visual Basic dil sürümünü ayarlama.

Bazı durumlarda, Visual Basic derleyicisi aday adından tanımlama grubu öğesi adını çıkaramaz ve tanımlama grubu alanına yalnızca varsayılan adı ( , Item1Item2vb.) kullanılarak başvurulabilir. Bunlar şunlardır:

  • Aday adı, , Restveya ToStringgibi Item3bir tanımlama grubu üyesinin adıyla aynıdır.

  • Aday adı tanımlama grubunda yineleniyor.

Alan adı çıkarımı başarısız olduğunda, Visual Basic derleyici hatası oluşturmaz ve çalışma zamanında bir özel durum oluşturmaz. Bunun yerine, tanımlama grubu alanlarına ve Item2gibi Item1 önceden tanımlanmış adlarıyla başvurulmalıdır.

Tanımlama demetleri ve yapılar karşılaştırması

Visual Basic tanımlama grubu, System.ValueTuple genel türlerinden birinin örneği olan bir değer türüdür. Örneğin, holiday önceki örnekte tanımlanan tanımlama grubu, yapının bir örneğidir ValueTuple<T1,T2,T3> . Veriler için basit bir kapsayıcı olacak şekilde tasarlanmıştır. Tanımlama grubu, birden çok veri öğesi içeren bir nesne oluşturmayı kolaylaştırmayı hedeflediğinden, özel bir yapının sahip olabileceği bazı özelliklerden yoksundur. Bu modüller şunlardır:

  • Özel üyeler. Bir tanımlama grubu için kendi özelliklerinizi, yöntemlerinizi veya olaylarınızı tanımlayamazsınız.

  • Doğrulama. Alanlara atanan verileri doğrulayamazsınız.

  • Immutability. Visual Basic tanımlama kümeleri değişebilir. Buna karşılık, özel bir yapı bir örneğin değişebilir mi yoksa sabit mi olduğunu denetlemenize olanak tanır.

Özel üyeler, özellik ve alan doğrulaması veya değişmezlik önemliyse, özel bir değer türü tanımlamak için Visual Basic Structure deyimini kullanmanız gerekir.

Visual Basic tanımlama grubu, ValueTuple türünün üyelerini devralır. Bu alanlar, alanlarına ek olarak aşağıdaki yöntemleri de içerir:

Metot Açıklama
Karşılaştır Geçerli tanımlama kümesini aynı sayıda öğeyle başka bir tanımlama grubuyla karşılaştırır.
Eşittir Geçerli demetin başka bir tanımlama grubuna veya nesneye eşit olup olmadığını belirler.
GetHashCode Geçerli örneğin karma kodunu hesaplar.
ToString Bu (Item1, Item2...)Item1 tanımlama grubunun dize gösterimini döndürür ve burada ve Item2 tanımlama grubu alanlarının değerlerini temsil eder.

Buna ek olarak, ValueTuple türleri özel karşılaştırıcılar tanımlamanızı sağlayan ve IStructuralEquatable arabirimleri uygularIStructuralComparable.

Atama ve tanımlama demetleri

Visual Basic, aynı sayıda alana sahip tanımlama grubu türleri arasında atamayı destekler. Aşağıdakilerden biri doğruysa alan türleri dönüştürülebilir:

  • Kaynak ve hedef alan aynı türdedir.

  • Kaynak türün hedef türe genişletilmesi (veya örtük) dönüştürülmesi tanımlanır.

  • Option Strict olur Onve kaynak türün hedef türe daraltma (veya açık) dönüştürmesi tanımlanır. Kaynak değer hedef türün aralığının dışındaysa bu dönüştürme özel durum oluşturabilir.

Atamalar için diğer dönüştürmeler dikkate alınmaz. Tanımlama grubu türleri arasında izin verilen atama türlerine göz atalım.

Aşağıdaki örneklerde kullanılan bu değişkenleri göz önünde bulundurun:

' The number and field types of all these tuples are compatible. 
' The only difference Is the field names being used.
Dim unnamed = (42, "The meaning of life")
Dim anonymous = (16, "a perfect square")
Dim named = (Answer:=42, Message:="The meaning of life")
Dim differentNamed = (SecretConstant:=42, Label:="The meaning of life")

ve ilk iki değişkeninin unnamed anonymousalanlar için semantik adları sağlanmaz. Alan adları varsayılan Item1 ve Item2şeklindedir. Son iki değişken ve named differentName anlamsal alan adları vardır. Bu iki demetin alanlar için farklı adlara sahip olduğunu unutmayın.

Bu tanımlama kümelerinin dördü de aynı sayıda alana ('arity' olarak adlandırılır) sahiptir ve bu alanların türleri aynıdır. Bu nedenle, bu atamaların tümü çalışır:

' Assign named to unnamed.
named = unnamed

' Despite the assignment, named still has fields that can be referred to as 'answer' and 'message'.
Console.WriteLine($"{named.Answer}, {named.Message}")
' Output:  42, The meaning of life

' Assign unnamed to anonymous.
anonymous = unnamed
' Because of the assignment, the value of the elements of anonymous changed.
Console.WriteLine($"{anonymous.Item1}, {anonymous.Item2}")
' Output:   42, The meaning of life

' Assign one named tuple to the other.
named = differentNamed
' The field names are Not assigned. 'named' still has 'answer' and 'message' fields.
Console.WriteLine($"{named.Answer}, {named.Message}")
' Output:   42, The meaning of life

Tanımlama listelerinin adlarının atanmadığına dikkat edin. Alanların değerleri, tanımlama grubundaki alanların sırasına göre atanır.

Son olarak, ilk alanı bir ve ilk alanı da bir Integerolsa bile, tanımlama grubunu tanımlama grubuna conversion Longatayabildiğimizi named conversion görebilirsiniz.named Bu atama başarılı olur çünkü bir'i Integer 'a Long dönüştürmek bir genişletme dönüştürmesidir.

' Assign an (Integer, String) tuple to a (Long, String) tuple (using implicit conversion).
Dim conversion As (Long, String) = named
Console.WriteLine($"{conversion.Item1} ({conversion.Item1.GetType().Name}), " +
                  $"{conversion.Item2} ({conversion.Item2.GetType().Name})")
' Output:      42 (Int64), The meaning of life (String)

Farklı sayıda alan içeren demetler atanamaz:

' Does not compile.
' VB30311: Value of type '(Integer, Integer, Integer)' cannot be converted
'          to '(Answer As Integer, Message As String)'
var differentShape = (1, 2, 3)
named = differentShape

Yöntem olarak demetler değer döndürür

Bir yöntem yalnızca tek bir değer döndürebilir. Ancak sık sık bir yöntem çağrısının birden çok değer döndürmesini istersiniz. Bu sınırlamayı geçici olarak gidermenin birkaç yolu vardır:

  • Özellikleri veya alanları yöntemi tarafından döndürülen değerleri temsil eden özel bir sınıf veya yapı oluşturabilirsiniz. Bu ağır bir çözümdür; tek amacı bir yöntem çağrısından değerleri almak olan özel bir tür tanımlamanızı gerektirir.

  • yönteminden tek bir değer döndürebilir ve kalan değerleri yöntemine başvurarak geçirerek döndürebilirsiniz. Bu, bir değişkenin örneğini oluşturma yükünü içerir ve başvuruya göre geçirdiğiniz değişkenin değerini yanlışlıkla üzerine yazma riski taşır.

  • Birden çok dönüş değeri almak için basit bir çözüm sağlayan bir tanımlama grubu kullanabilirsiniz.

Örneğin, .NET'teki TryParse yöntemleri ayrıştırma işleminin başarılı olup olmadığını gösteren bir Boolean değer döndürür. Ayrıştırma işleminin sonucu, yöntemine başvuru ile geçirilen bir değişkende döndürülür. Normalde Integer.TryParse gibi bir ayrıştırma yöntemine yapılan çağrı aşağıdaki gibi görünür:

Dim numericString As String = "123456"
Dim number As Integer
Dim result = Integer.TryParse(numericString, number)
Console.WriteLine($"{If(result, $"Success: {number:N0}", "Failure")}")
'      Output: Success: 123,456

Çağrıyı kendi yöntemimizde Integer.TryParse yöntemine sarmalarsak ayrıştırma işleminden bir tanımlama grubu döndürebiliriz. Aşağıdaki örnekte Integer.TryParse NumericLibrary.ParseInteger yöntemini çağırır ve iki öğe içeren adlandırılmış bir tanımlama grubu döndürür.

Imports System.Globalization

Public Module NumericLibrary
    Public Function ParseInteger(value As String) As (Success As Boolean, Number As Integer)
        Dim number As Integer
        Return (Integer.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, number), number)
    End Function
End Module

Ardından yöntemini aşağıdaki gibi bir kodla çağırabilirsiniz:

Dim numericString As String = "123,456"
Dim result = ParseInteger(numericString)
Console.WriteLine($"{If(result.Success, $"Success: {result.Number:N0}", "Failure")}")
Console.ReadLine()
'      Output: Success: 123,456

.NET Framework'te Visual Basic tanımlama kümeleri ve tanımlama kümeleri

Visual Basic tanımlama grubu, .NET Framework 4.7'de kullanıma sunulan System.ValueTuple genel türlerinden birinin örneğidir. .NET Framework ayrıca bir dizi genel System.Tuple sınıfı içerir. Ancak bu sınıflar, Visual Basic tanımlama gruplarından ve System.ValueTuple genel türlerinden çeşitli yollarla farklıdır:

  • Tanımlama Grubu sınıflarının öğeleri , Item2ve benzeri adlı Item1özelliklerdir. Visual Basic tanımlama demetleri ve ValueTuple türlerinde tanımlama grubu öğeleri alanlardır.

  • Bir Tanımlama Grubu örneğinin veya ValueTuple örneğinin öğelerine anlamlı adlar atayamazsınız. Visual Basic, alanların anlamını belirten adlar atamanızı sağlar.

  • Bir Tanımlama Grubu örneğinin özellikleri salt okunur; tanımlama kümeleri sabittir. Visual Basic tanımlama demetleri ve ValueTuple türlerinde tanımlama grubu alanları okuma-yazma; tanımlama kümeleri değiştirilebilir.

  • Genel Tanımlama Grubu türleri başvuru türleridir. Bu Tanımlama Grubu türlerini kullanmak, nesneleri ayırma anlamına gelir. Sık erişimli yollarda bu, uygulamanızın performansı üzerinde ölçülebilir bir etkiye sahip olabilir. Visual Basic tanımlama kümeleri ve ValueTuple türleri değer türleridir.

Sınıfındaki TupleExtensions uzantı yöntemleri, Visual Basic tanımlama kümeleri ile .NET Tanımlama Grubu nesneleri arasında dönüştürmeyi kolaylaştırır. ToTuple yöntemi bir Visual Basic tanımlama kümesini .NET Tanımlama Grubu nesnesine, ToValueTuple yöntemi ise bir .NET Tanımlama Grubu nesnesini Visual Basic tanımlama grubuna dönüştürür.

Aşağıdaki örnek bir tanımlama grubu oluşturur, bunu bir .NET Tanımlama Grubu nesnesine dönüştürür ve bir Visual Basic tanımlama grubuna geri dönüştürür. Örnek daha sonra eşit olduklarından emin olmak için bu tanımlama grubu ile özgün grubu karşılaştırır.

Dim cityInfo = (name:="New York", area:=468.5, population:=8_550_405)
Console.WriteLine($"{cityInfo}, type {cityInfo.GetType().Name}")

' Convert the Visual Basic tuple to a .NET tuple.
Dim cityInfoT = TupleExtensions.ToTuple(cityInfo)
Console.WriteLine($"{cityInfoT}, type {cityInfoT.GetType().Name}")

' Convert the .NET tuple back to a Visual Basic tuple and ensure they are the same.
Dim cityInfo2 = TupleExtensions.ToValueTuple(cityInfoT)
Console.WriteLine($"{cityInfo2}, type {cityInfo2.GetType().Name}")
Console.WriteLine($"{NameOf(cityInfo)} = {NameOf(cityInfo2)}: {cityInfo.Equals(cityInfo2)}")

' The example displays the following output:
'       (New York, 468.5, 8550405), type ValueTuple`3
'       (New York, 468.5, 8550405), type Tuple`3
'       (New York, 468.5, 8550405), type ValueTuple`3
'       cityInfo = cityInfo2 :  True

Ayrıca bkz.