Aracılığıyla paylaş


Tanımlama Kümeleri (Visual Basic)

Visual Basic 2017'den itibaren, Visual Basic dili tuple'lar için yerleşik destek sunarak, tuple oluşturmayı ve tuple öğelerine erişimi kolaylaştırmaktadır. Bir tuple, belirli bir sayıda ve sıralamada değerlere sahip, hafif 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, ikili (veya çift) iki öğeden oluşur. birincisi bir Boolean değer, ikincisi ise bir Stringolabilir. Tuple'lar, birden fazla değeri tek bir nesnede depolamayı kolaylaştırdığı için, genellikle bir yöntemden birden fazla değer döndürmenin hafif ve pratik bir yolu olarak kullanılır.

Önemli

Demet desteği, ValueTuple türünü 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.

Tuple oluşturma ve kullanma

Virgülle ayrılmış değerleri parantez içine alarak bir tuple oluşturursunuz. Bu değerlerin her biri, demetin bir alanı haline gelir. Örneğin, aşağıdaki kod, ilk değeri Date, ikinci değeri String ve üçüncü değeri Boolean olan bir üçlü (veya 3'lü küme) 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'lü için, Date alanı Item1 değerindedir, String alanı Item2 değerindedir ve Boolean alanı Item3 değerindedir. Önceki kod satırında oluşturulan demet alanlarının değerlerini, aşağıdaki örnek 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 kümedeki üç 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 tuple örneği oluşturma ve kullanma

Varsayılan adları kullanmak yerine, bir adlandırılmış demet örneğini, demetin öğelerine kendi adlarınızı atayarak oluşturabilirsiniz. Tanımlama grubu (tuple) alanlarına, atanan adlarıyla veya varsayılan adlarıyla erişilebilir. Aşağıdaki örnek, ilk alanın EventDate, ikinci alanın Name, ve üçüncü alanın IsHoliday olarak açıkça adlandırılması dışında, daha önce olduğu gibi aynı 3'lü örneği 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 tuple sağlarken kullanışlıdır; tuple adları koleksiyonun tür bildirimine dahil edilebilir.

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'ten itibaren, Visual Basic tuple öğelerinin adlarını tahmin edebilir; bunları açıkça atamanız gerekmez. Değişkenlerden bir demet başlattığınızda ve demet öğesinin adının değişken adıyla aynı olmasını istediğinizde, çıkarılmış demet adları yararlıdır.

Aşağıdaki örnek, stateInfo, state ve stateName olarak açıkça adlandırılmış üç öğe içeren bir capital sınıfı oluşturur. Öğeleri adlandırdığınızda, tuple başlatma deyiminin isimlendirilmiş öğelere aynı isimli değişkenlerin değerlerini atadığını unutmayın.

Const state As String = "MI"
Const stateName As String = "Michigan"
Dim stateInfo = (state:=state, stateName:=stateName)
Console.WriteLine($"{stateInfo.stateName}: 2-letter code: {stateInfo.state}")
' 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 katar öğe adlarını etkinleştirmek için, Visual Basic projeniz (*.vbproj) dosyasında 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ı, Item3, Rest veya ToString gibi bir demet üyesinin adıyla aynıdır.

  • Aday adı tuple içinde 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, kartil alanlarına önceden tanımlanmış Item1 ve Item2 gibi adlarıyla başvurulmalıdır.

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

Visual Basic tuple'ı, System.ValueTuple genel türlerinden birinin örneği olan bir değer türüdür. Örneğin, holiday önceki örnekte tanımlanan tuple, ValueTuple<T1,T2,T3> yapının bir örneğidir. Veriler için basit bir kapsayıcı olacak şekilde tasarlanmıştır. Demet, birden çok veri öğesi içeren bir nesne oluşturmayı kolaylaştırmayı amaçladığından, özel bir yapının sahip olabileceği bazı özelliklere sahip değildir. Bunlar şunlardır:

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

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

  • Değişmezlik 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 demeti, ValueTuple türünün üyelerini devralır. 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 demet veya nesne ile eşit olup olmadığını belirler.
GetHashCode Geçerli örneğin karma kodunu hesaplar.
ToString Bu tuple'ın (Item1, Item2...) biçiminde olan dize gösterimini döndürür; burada Item1 ve Item2, tuple'ın alanlarının değerlerini temsil eder.

Buna ek olarak, ValueTuple türleri IStructuralComparable ve IStructuralEquatable arabirimlerini uygulayarak özel karşılaştırıcılar tanımlamanıza olanak tanır.

Atama ve tanımlama demetleri

Visual Basic, aynı sayıda alana sahip demet 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 ise On, ve kaynak türün hedef türe daraltma (veya açık) dönüşümü 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")

İlk iki değişken, unnamed ve anonymous, alanlar için semantik adlar sağlanmamıştır. Alan adları varsayılan Item1 ve Item2şeklindedir. Son iki değişken ve nameddifferentName anlamsal alan adları vardır. Bu iki tuple’ın alanlar için farklı adlara sahip olduğunu unutmayın.

Bu tanımlama kümelerinin dördü de aynı sayıda alana sahiptir (bu, 'arity' olarak adlandırılır) ve bu alanların türleri de 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

Demetlerin 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, named'nin ilk alanı bir Integer ve conversion'ün ilk alanı bir Long olmasına rağmen, named tanımlama grubunu conversion tanımlama grubuna atayabildiğimizi görebilirsiniz. Bu atama başarılıdır çünkü Integer nesnesinin Long nesnesine dönüştürülmesi genişletilmiş bir dönüşümdür.

' 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.

  • Metottan tek bir değer döndürebilir ve geri kalan değerleri metota referansla geçirerek döndürebilirsiniz. Bu, bir değişkenin oluşturulmasının getirdiği yükü içerir ve başvuru ile ilettiğiniz değişkenin değerini yanlışlıkla üzerine yazma riski taşır.

  • Birden çok dönüş değeri almak için hafif bir çözüm sağlayan bir demet 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, referansla metoda 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

Kendi metodumuzla Integer.TryParse çağrısını sarmalarsak, ayrıştırma işleminden bir demet döndürebiliriz. Aşağıdaki örnekte, NumericLibrary.ParseIntegerInteger.TryParse 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 tuple, .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:

  • Tuple sınıflarının öğeleri, Item1, Item2 ve benzeri adlarla anılan özelliklerdir. Visual Basic'teki demetler ve ValueTuple türlerinde, demet öğeleri alanlardır.

  • Bir Tuple örneğinin veya bir 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'teki demetler ve ValueTuple türlerinde demet alanları okuma-yazma özelliğine sahiptir; demetler değiştirilebilir.

  • Genel Tuple türleri başvuru türleridir. Bu Tuple türlerini kullanmak, nesneleri tahsis etme 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 tuple oluşturur, bunu bir .NET Tuple nesnesine dönüştürür ve bir Visual Basic tuple'ına 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.