Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
A Visual Basic 2017-től kezdve a Visual Basic nyelv beépített támogatást nyújt a kukákhoz, amelyek megkönnyítik a csuplok létrehozását és az elemek elérését. A rekord egy egyszerű adatstruktúra, amely meghatározott számú és értéksorozatú. A rekord példányosításakor meg kell határoznia az egyes értékek (vagy elemek) számát és adattípusát. Egy kétfős (vagy páros) két elemből áll. Az első lehet érték Boolean , míg a második egy String. Mivel a kukák megkönnyítik több érték egyetlen objektumban való tárolását, gyakran egyszerű módszerként használják őket, hogy több értéket adjanak vissza egy metódusból.
Fontos
A tuple-támogatáshoz a típus szükséges ValueTuple . Ha a .NET-keretrendszer 4.7 nincs telepítve, hozzá kell adnia a NuGet-csomagotSystem.ValueTuple, amely elérhető a NuGet-katalógusban. A csomag nélkül a következőhöz hasonló fordítási hibát kaphat: "Az előre definiált "ValueTuple(Of,,,)" típus nincs definiálva vagy importálva."
Példányok létrehozása és használata
A vesszővel tagolt értékeket zárójelekbe foglalva példányosíthatja a rekordokat. Ezek az értékek ezután a rekord mezőivé válnak. A következő kód például egy triplát (vagy 3-rekordot) Date határoz meg első értékként, String másodikként és Boolean harmadikként.
Dim holiday = (#07/04/2017#, "Independence Day", True)
Alapértelmezés szerint a rekord egyes mezőinek neve a sztringből Item és a mező egy-alapú pozíciójából áll a rekordban. Ebben a 3 rekordban a Date mező az , a Item1 mező Stringpedig az Item2Boolean.Item3 Az alábbi példa az előző kódsorban példányosított rekord mezőinek értékeit jeleníti meg
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
A Visual Basic-rekordok mezői írás-olvasás; miután példányosított egy rekordot, módosíthatja annak értékeit. Az alábbi példa az előző példában létrehozott rekord három mezőjéből kettőt módosít, és megjeleníti az eredményt.
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
Névvel ellátott rekord példányosítása és használata
Ahelyett, hogy alapértelmezett neveket használ egy rekord mezőihez, létrehozhat egy elnevezett rekordot úgy, hogy saját neveket rendel a rekord elemeihez. A rekord mezői ezután a hozzárendelt nevek vagy az alapértelmezett nevük alapján érhetők el. Az alábbi példa ugyanazt a 3 rekordot példányosítja, mint korábban, azzal a kivételt leszámítva, hogy kifejezetten az első mezőt, a másodikat EventDateés a harmadikat NameIsHolidayadja meg. Ezután megjeleníti a mezőértékeket, módosítja őket, és ismét megjeleníti a mezőértékeket.
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
A rekordneveket egy változó, mező vagy paraméter típusdeklarációjának részeként is megadhatja:
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
vagy egy metódus visszatérési típusában.
Ez különösen akkor hasznos, ha a gyűjtemény inicializálója számára biztosít műveletet; a rekordnevek a gyűjtemény típusdeklarációjának részeként adhatók meg:
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
Kikövetkesedő elemnevek
A Visual Basic 15.3-tól kezdve a Visual Basic képes a rekordelemek nevére következtetni; nem kell explicit módon hozzárendelnie őket. A kikövetkeztetett rekordnevek akkor hasznosak, ha változókészletből inicializál egy rekordot, és azt szeretné, hogy a rekordelem neve megegyezik a változó nevével.
Az alábbi példa létrehoz egy rekordotstateInfo, amely három, kifejezetten elnevezett elemet tartalmaz, statestateNameés capital. Vegye figyelembe, hogy az elemek elnevezésekor a rekord inicializálási utasítása egyszerűen hozzárendeli az elnevezett elemeket az azonos nevű változók értékeihez.
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
Mivel az elemeknek és a változóknak ugyanaz a neve, a Visual Basic fordító a mezők neveiből következtethet, ahogy az alábbi példa is mutatja.
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
A kikövetkeztetett elemnevek engedélyezéséhez meg kell határoznia a Visual Basic-fordító visual basic projektfájlban (*.vbproj) használandó verzióját:
<PropertyGroup>
<LangVersion>15.3</LangVersion>
</PropertyGroup>
A verziószám a Visual Basic fordító 15.3-tól kezdődő bármely verziója lehet. Egy adott fordítóverzió kemény kódolása helyett a "Latest" értéket is megadhatja a rendszerére telepített Visual Basic fordító legújabb verziójával való fordítás értékeként LangVersion .
További információ: A Visual Basic nyelvi verziójának beállítása.
Bizonyos esetekben a Visual Basic fordító nem tudja kikövetkeztetni a rekordelem nevét a jelölt névből, és a rekordmezőre csak az alapértelmezett nevével lehet hivatkozni, például Item1: , Item2stb. Ezek a következők:
A jelölt neve megegyezik a tag nevével, például
Item3: ,RestvagyToString.A jelölt neve duplikálva lesz a rekordban.
Ha a mezőnév-következtetés sikertelen, a Visual Basic nem hoz létre fordítóhibát, és a futtatáskor sem keletkezik kivétel. Ehelyett a rekordmezőkre az előre definiált neveknek kell hivatkozniuk, például Item1 és Item2.
Üstkék és struktúrák
A Visual Basic-rekord olyan értéktípus, amely a System.ValueTuple általános típusainak egyik példánya. Az előző példában definiált rekord például holiday a ValueTuple<T1,T2,T3> struktúra egy példánya. Úgy tervezték, hogy egy egyszerű tároló az adatok számára. Mivel a rekord célja, hogy megkönnyítse egy több adatelemet tartalmazó objektum létrehozását, nem rendelkezik az egyéni struktúra egyes funkcióival. Ezek közé tartoznak:
Egyéni tagok. Nem definiálhat saját tulajdonságokat, metódusokat vagy eseményeket egy rekordhoz.
Érvényesítés. A mezőkhöz rendelt adatok nem érvényesíthetők.
Nem módosítható. A Visual Basic-tuplesek nem módosíthatók. Ezzel szemben az egyéni struktúra lehetővé teszi annak szabályozását, hogy egy példány nem módosítható vagy módosítható-e.
Ha az egyéni tagok, a tulajdonság- és mezőérvényesítés, illetve a nem módosíthatóság fontos, a Visual Basic Structure utasítással definiálhat egyéni értéktípust.
A Visual Basic-rekord örökli a ValueTuple típus tagjait. A mezők mellett ezek a következő módszereket is tartalmazzák:
| Metódus | Leírás |
|---|---|
| Összehasonlítás | Összehasonlítja az aktuális rekordot egy másik rekorddal ugyanazzal az elemszámmal. |
| Egyenlő | Meghatározza, hogy az aktuális rekord egyenlő-e egy másik rekordmal vagy objektummal. |
| Hash-kód beszerzése | Kiszámítja az aktuális példány kivonatkódját. |
| ToString (objektum sztringgé alakítása) | Ennek a rekordnak a sztring-ábrázolását adja vissza, amely az űrlapot (Item1, Item2...)veszi fel, ahol Item1 és Item2 a rekord mezőinek értékeit jeleníti meg. |
Emellett a ValueTuple típusok implementálhatók IStructuralComparable és IStructuralEquatable interfészek, amelyek lehetővé teszik egyéni összehasonlítók definiálásához.
Hozzárendelés és csuples
A Visual Basic támogatja az azonos számú mezővel rendelkező rekordtípusok közötti hozzárendelést. A mezőtípusok konvertálhatók, ha az alábbiak egyike igaz:
A forrás és a célmező azonos típusú.
Meg van határozva a forrástípus céltípusra való kibővítése (vagy implicit) átalakítása.
Option Strictaz ,Onés a forrástípus céltípusra való szűkítése (vagy explicit) konvertálása meg van határozva. Ez az átalakítás kivételt okozhat, ha a forrásérték kívül esik a céltípus tartományán.
Más átalakítások nem tekinthetők hozzárendeléseknek. Nézzük meg, hogy milyen típusú feladatok engedélyezettek a rekordtípusok között.
Vegye figyelembe az alábbi példákban használt változókat:
' 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")
Az első két változó unnamedanonymousnem tartalmaz szemantikai neveket a mezőkhöz. A mezőnevek az alapértelmezettek Item1 és Item2a . Az utolsó két változó szemantikai nameddifferentName mezőnevekkel rendelkezik. Vegye figyelembe, hogy ez a két vonás különböző neveket tartalmaz a mezőkhöz.
E rekordok mind a négye azonos számú mezővel rendelkezik (más néven arity), és ezeknek a mezőknek a típusai azonosak. Ezért ezek a feladatok a következők:
' 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
Figyelje meg, hogy a csuplok neve nincs hozzárendelve. A mezők értékei a rekord mezőinek sorrendjét követve vannak hozzárendelve.
Végül figyelje meg, hogy a rekordot hozzárendelhetjük a namedconversion rekordhoz, annak ellenére, hogy az első mező named egy Integer, az első mező conversion pedig egy Long. Ez a hozzárendelés sikeres, mert az átalakítás IntegerLong egy egyre szélesebb körű átalakítás.
' 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)
A különböző számú mezővel rendelkező rekordok nem rendelhetők hozzá:
' 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
Típusok mint metódus visszatérési értékek
A metódusok csak egyetlen értéket adhatnak vissza. Gyakran azonban több értéket szeretne visszaadni egy metódushívással. Ennek a korlátozásnak több módja is van:
Létrehozhat olyan egyéni osztályt vagy struktúrát, amelynek tulajdonságai vagy mezői a metódus által visszaadott értékeket jelölik. Ez egy nehézsúlyú megoldás; ehhez olyan egyéni típust kell definiálnia, amelynek egyetlen célja az értékek lekérése egy metódushívásból.
A metódusból egyetlen értéket ad vissza, a fennmaradó értékeket pedig a metódusra való hivatkozással adja vissza. Ez magában foglalja egy változó példányosításának többletterhelését, és azzal a kockázattal jár, hogy véletlenül felülírja a hivatkozással átadott változó értékét.
Használhat egy rekordot, amely egyszerű megoldást kínál több visszatérési érték lekérésére.
A .NET TryParse metódusai például olyan Boolean értéket adnak vissza, amely jelzi, hogy az elemzési művelet sikeres volt-e. Az elemzési művelet eredménye egy, a metódusra hivatkozva átadott változóban lesz visszaadva. Általában egy elemzési metódusra(például az Integer.TryParse ) való hívás a következőhöz hasonlóan néz ki:
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
Az elemzési műveletből vissza tudunk adni egy rekordot, ha az Integer.TryParse metódus hívását a saját metódusunkba csomagoljuk. Az alábbi példában meghívja az NumericLibrary.ParseInteger metódust, és egy elnevezett rekordot ad vissza két elemből.
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
Ezután az alábbihoz hasonló kóddal hívhatja meg a metódust:
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
Visual Basic-tuples és -csuples a .NET-keretrendszer
A Visual Basic tuple a System.ValueTuple általános típus egyik példánya, amelyet a 4.7-.NET-keretrendszer vezettünk be. A .NET-keretrendszer általános System.Tuple-osztályokat is tartalmaz. Ezek az osztályok azonban számos módon különböznek a Visual Basic-tuplestől és a System.ValueTuple általános típustól:
A Tuple-osztályok elemei a tovább. A Visual Basic-rekordokban és a ValueTuple-típusokban a rekordelemek mezők.
Nem rendelhet hozzá értelmes neveket egy Tuple-példány vagy egy ValueTuple-példány elemeihez. A Visual Basic lehetővé teszi olyan nevek hozzárendelését, amelyek közlik a mezők jelentését.
A Tuple-példányok tulajdonságai írásvédettek, a rekordok nem módosíthatók. A Visual Basic-rekordokban és a ValueTuple-típusokban a rekordmezők írás-olvasás, a rekordok pedig módosíthatók.
Az általános Tuple-típusok referenciatípusok. Ezeknek a Tuple-típusoknak a használata objektumok kiosztását jelenti. A gyakori elérésű útvonalakon ez mérhető hatással lehet az alkalmazás teljesítményére. A Visual Basic rekordjai és a ValueTuple-típusok értéktípusok.
Az osztály bővítménymetódusai megkönnyítik a TupleExtensions Visual Basic-rekordok és a .NET Tuple-objektumok közötti konvertálást. A ToTuple metódus .NET Tuple objektummá alakítja a Visual Basic rekordokat, a ToValueTuple metódus pedig a .NET Tuple objektumot Visual Basic rekordmá alakítja.
Az alábbi példa létrehoz egy rekordot, .NET Tuple objektummá alakítja át, és visszaalakít egy Visual Basic-rekordra. A példa ezután összehasonlítja ezt a rekordot az eredetivel annak biztosítása érdekében, hogy egyenlőek legyenek.
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