Řazené kolekce členů (Visual Basic)
Počínaje Visual Basic 2017 jazyk Visual Basic nabízí integrovanou podporu pro řazené kolekce členů, která usnadňuje vytváření řazených kolekce členů a přístup k prvkům řazených kolekce členů. Řazená kolekce členů je zjednodušená datová struktura, která má určitý počet a posloupnost hodnot. Při vytváření instance řazené kolekce členů definujete číslo a datový typ každé hodnoty (nebo elementu). Například řazená kolekce členů se dvěma členy (nebo dvojice) má dva prvky. První může být Boolean hodnota, zatímco druhá je String . Vzhledem k tomu, že řazené kolekce členů usnadňuje ukládání více hodnot v jednom objektu, často se používají jako jednoduchý způsob vrácení více hodnot z metody.
Důležité
Podpora řazené kolekce členů vyžaduje ValueTuple typ . Pokud není .NET Framework verze 4.7 nainstalovaná, musíte přidat balíček NuGet , který je k dispozici v System.ValueTuple NuGet Gallery. Bez tohoto balíčku se může zobrazit chyba kompilace typu Předdefinovaný typ ValueTuple(Of,,,) není definovaný nebo importovaný.
Vytvoření instance a použití řazené kolekce členů
Instanci řazené kolekce členů vytváříte uzavřením hodnot oddělených čárkami do závorek. Každá z těchto hodnot se pak stane polem řazené kolekce členů. Například následující kód definuje trojitou (nebo 3-tuple) s první hodnotou, druhou hodnotou a třetí Date String Boolean hodnotou .
Dim holiday = (#07/04/2017#, "Independence Day", True)
Ve výchozím nastavení se název každého pole v řazené řazené kolekce členů skládá z řetězce společně s jednou pozicí pole Item v řazené kolekce členů. Pro tuto řazenou kolekce členů se 3 řazené kolekce členů používá pole , pole je a Date Item1 pole je String Item2 Boolean Item3 . Následující příklad zobrazí hodnoty polí instance řazené kolekce členů v předchozím řádku kódu.
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
Pole řazené kolekce Visual Basic jsou pro čtení i zápis. Po vytvoření instance řazené kolekce členů můžete upravit její hodnoty. Následující příklad upraví dvě ze tří polí řazené kolekce členů vytvořené v předchozím příkladu a zobrazí výsledek.
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
Vytvoření instance a použití pojmenované řazené kolekce členů
Místo použití výchozích názvů pro pole řazené kolekce členů můžete vytvořit instanci pojmenované řazené kolekce členů přiřazením vlastních názvů k prvkům řazené kolekce členů. Pole řazené kolekce členů jsou pak přístupná podle jejich přiřazených názvů nebo jejich výchozích názvů. Následující příklad vytvoří instanci stejné řazené kolekce členů 3 jako dříve s tím rozdílem, že explicitně najme první pole , druhý a EventDate Name třetí IsHoliday . Pak zobrazí hodnoty polí, upraví je a znovu zobrazí hodnoty polí.
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
Odvozené názvy elementů řazené kolekce členů
Počínaje Visual Basic 15.3 může Visual Basic odvodit názvy elementů řazené kolekce členů. Není nutné je přiřazovat explicitně. Odvozené názvy řazené kolekce členů jsou užitečné při inicializaci řazené kolekce členů ze sady proměnných a chcete, aby název elementu řazené kolekce členů byl stejný jako název proměnné.
Následující příklad vytvoří stateInfo řazenou kolekce členů, která obsahuje tři explicitně pojmenované elementy state , a stateName capital . Všimněte si, že při pojmenování elementů příkaz inicializace řazené kolekce členů jednoduše přiřadí pojmenované prvky hodnoty stejně pojmenovaných proměnných.
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
Vzhledem k tomu, že prvky a proměnné mají stejný název, Visual Basic kompilátor odvodí názvy polí, jak ukazuje následující příklad.
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
Pokud chcete povolit odvozené názvy elementů řazené kolekce členů, musíte definovat verzi kompilátoru Visual Basic, která se má použít v souboru Visual Basic projektu ( * .vbproj):
<PropertyGroup>
<LangVersion>15.3</LangVersion>
</PropertyGroup>
Číslo verze může být libovolná verze kompilátoru Visual Basic počínaje verzí 15.3. Místo pevného kódování konkrétní verze kompilátoru můžete také zadat "Latest" jako hodnotu pro kompilaci s nejnovější verzí kompilátoru Visual Basic nainstalovanou LangVersion ve vašem systému.
Další informace najdete v tématu nastavení Visual Basic jazyka.
V některých případech kompilátor Visual Basic nemůže odvodit název elementu řazené kolekce členů z názvu kandidáta a na pole řazené kolekce členů lze odkazovat pouze pomocí výchozího názvu, například Item1 Item2 , atd. Patří mezi ně:
Název kandidáta je stejný jako název člena řazené kolekce členů, například
Item3Rest, neboToString.Název kandidáta je duplicitní v řazené kolekce členů.
Pokud se odvození názvu pole nezdaří, Visual Basic negeneruje chybu kompilátoru, ani není vyvolána výjimka za běhu. Místo toho musí být pole řazené kolekce členů odkazována jejich předdefinovanými názvy, například Item1 a Item2 .
Řazené kolekce členů versus struktury
Typ Visual Basic je typ hodnoty, který je instancí jednoho z obecných typů System.ValueTuple. Například holiday řazená kolekce členů definovaná v předchozím příkladu je instancí ValueTuple<T1,T2,T3> struktury. Je navržený jako jednoduchý kontejner pro data. Vzhledem k tomu, že cílem řazené kolekce členů je snadno vytvořit objekt s více datovými položkami, chybí mu některé funkce, které může mít vlastní struktura. Tady jsou některé z nich:
Vlastní členy. Pro řazenou kolekce členů nelze definovat vlastní vlastnosti, metody nebo události.
Ověření. Data přiřazená k polím nelze ověřit.
Neměnnost: Visual Basic řazené kolekce členů jsou směšitelné. Vlastní struktura vám naproti tomu umožňuje řídit, jestli je instance neměnná nebo neměnná.
Pokud jsou důležité vlastní členy, ověřování vlastností a polí nebo neměnnost, měli byste k definování vlastního typu hodnoty použít příkaz Visual Basic Structure.
Řazená Visual Basic členů dědí členy svého typu ValueTuple. Kromě polí jsou mezi ně zahrnuty následující metody:
| Metoda | Popis |
|---|---|
| Compareto | Porovná aktuální řazenou kolekce členů s jinou řazenou kolekce členů se stejným počtem prvků. |
| Je rovno | Určuje, zda je aktuální řazená kolekce členů rovna jiné řazené kolekce členů nebo objektu. |
| Gethashcode | Vypočítá kód hash pro aktuální instanci. |
| ToString | Vrátí řetězcovou reprezentaci této řazené kolekce členů, která má tvar , kde a představují hodnoty polí (Item1, Item2...) Item1 Item2 řazené kolekce členů. |
Kromě toho implementují typy ValueTuple rozhraní a , která umožňují IStructuralComparable definovat vlastní IStructuralEquatable porovnávače.
Přiřazení a řazené kolekce členů
Visual Basic podporuje přiřazení mezi typy řazené kolekce členů, které mají stejný počet polí. Typy polí lze převést, pokud platí jedna z následujících podmínek:
Zdrojové a cílové pole jsou stejného typu.
Je definován rozšiřující (nebo implicitní) převod typu zdroje na cílový typ.
Option StrictjeOna je definován zužující (nebo explicitní) převod typu zdroje na cílový typ. Tento převod může vyvolat výjimku, pokud je zdrojová hodnota mimo rozsah cílového typu.
Jiné převody se pro přiřazení nezovažuje. Podívejme se na typy přiřazení, které jsou povolené mezi typy řazené kolekce členů.
Vezměte v úvahu tyto proměnné použité v následujících příkladech:
' 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")
První dvě proměnné, a , nemají pro pole zadané sémantické unnamed anonymous názvy. Jejich názvy polí jsou výchozí a Item1 Item2 . Poslední dvě proměnné a named mají differentName názvy sémantických polí. Všimněte si, že tyto dvě řazené kolekce členů mají pro pole různé názvy.
Všechny čtyři z těchto řazených kolekce členů mají stejný počet polí (označuje se jako "arity"), a typy těchto polí jsou identické. Proto všechna tato přiřazení fungují:
' 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
Všimněte si, že názvy řazených kolekce členů nejsou přiřazeny. Hodnoty polí jsou přiřazeny podle pořadí polí v řazené kolekce členů.
Nakonec si všimněte, že řazenou kolekce členů můžeme přiřadit řazené kolekce členů, i když je prvním polem , a prvním named conversion named Integer conversion polem je Long . Toto přiřazení je úspěšné, protože převod typu na typ je Integer Long rozšiřující převod.
' 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)
Řazené kolekce členů s různým počtem polí nelze přiřadit:
' 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
Řazené kolekce členů jako návratové hodnoty metody
Metoda může vrátit pouze jednu hodnotu. Často ale chcete, aby volání metody vrátilo více hodnot. Toto omezení můžete obejít několika způsoby:
Můžete vytvořit vlastní třídu nebo strukturu, jejichž vlastnosti nebo pole představují hodnoty vrácené metodou . Proto je řešení s velmi těžkou zátěží. Vyžaduje, abyste definujte vlastní typ, jehož jediným účelem je načtení hodnot z volání metody.
Můžete vrátit jednu hodnotu z metody a vrátit zbývající hodnoty jejich předáním odkazem na metodu . To zahrnuje režii vytvoření instance proměnné a rizika neúmyslně přepíše hodnotu proměnné, kterou předáte odkazem.
Můžete použít řazenou kolekce členů, která poskytuje jednoduché řešení pro načtení více vrácených hodnot.
Například metody TryParse v rozhraní .NET vrátí hodnotu, která označuje, zda byla operace analýzy Boolean úspěšná. Výsledek operace analýzy se vrátí v proměnné předané odkazem na metodu . V normálním případě volání metody analýzy, například vypadá takto Int32.TryParse :
Dim numericString As String = "123456"
Dim number As Integer
Dim result = Int32.TryParse(numericString, number)
Console.WriteLine($"{If(result, $"Success: {number:N0}", "Failure")}")
' Output: 123,456
Můžete vrátit řazenou kolekci členů z operace analýzy, pokud zabalíme volání Int32.TryParse metody v naší vlastní metodě. V následujícím příkladu NumericLibrary.ParseInteger volá Int32.TryParse metodu a vrátí pojmenované řazené kolekce členů se dvěma prvky.
Imports System.Globalization
Public Module NumericLibrary
Public Function ParseInteger(value As String) As (Success As Boolean, Number As Int32)
Dim number As Integer
Return (Int32.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, number), number)
End Function
End Module
Pak můžete zavolat metodu s kódem podobným následujícímu:
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 řazené kolekce členů a řazené kolekce členů v .NET Framework
Visual Basic řazená kolekce členů je instancí jednoho z obecných typů System. ValueTuple , které byly představeny v .NET Framework 4,7. .NET Framework také obsahuje sadu obecných tříd System. Tuple . tyto třídy se však liší od Visual Basicch řazených kolekcí členů a obecných typů System. ValueTuple mnoha různými způsoby:
Prvky tříd řazené kolekce členů jsou vlastnosti s názvem
Item1,Item2a tak dále. v Visual Basic řazené kolekce členů a typy ValueTuple jsou prvky řazené kolekce členů pole.K prvkům instance řazené kolekce členů nebo instanci ValueTuple nelze přiřadit smysluplné názvy. Visual Basic umožňuje přiřadit názvy, které komunikují význam polí.
Vlastnosti instance řazené kolekce členů jsou jen pro čtení; řazené kolekce členů jsou neměnné. v Visual Basic řazené kolekce členů a typy ValueTuple jsou pole řazené kolekce členů i pro čtení i zápis; řazené kolekce členů jsou proměnlivé.
Obecné typy řazené kolekce členů jsou odkazové typy. Použití těchto typů řazené kolekce členů znamená přidělení objektů. U aktivních cest to může mít měřitelný dopad na výkon vaší aplikace. Visual Basic řazené kolekce členů a typy ValueTuple jsou typy hodnot.
metody rozšíření ve třídě usnadňují TupleExtensions konverzi mezi Visual Basicmi řazenými kolekcemi členů a objekty v řazené kolekci členů .net. metoda ToTuple převádí Visual Basic řazené kolekce členů na objekt .net řazené kolekce členů a metoda ToValueTuple převede objekt řazené kolekce členů .net na Visual Basic řazené kolekce členů.
následující příklad vytvoří řazenou kolekci členů, převede ji na objekt řazené kolekce členů .net a převede ji zpět na Visual Basic řazené kolekce členů. Příklad následně Porovná tuto řazenou kolekci členů s původní verzí, aby se zajistilo, že jsou stejné.
Module Example
Sub Main()
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)}")
Console.ReadLine()
End Sub
End Module
' 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