Použití typů záznamů

Tip

Začínáte s vývojem softwaru? Začněte nejprve kurzy Začínáme . Seznámíte se s třídami, metodami a smyčkami.

Máte zkušenosti v jiném jazyce? Tento kurz se zaměřuje na funkce záznamů jazyka C#, které používáte každý den: rovnost hodnot, poziční syntaxi a with výrazy.

V tomto kurzu vytvoříte konzolovou aplikaci, která modeluje denní teploty pomocí záznamů a struktur záznamů.

V tomto návodu se naučíte, jak:

  • Deklarujte poziční záznamy a struktury záznamů.
  • Vytvořte malou hierarchii záznamů.
  • Použijte rovnost a formátování generované kompilátorem.
  • Používejte with výrazy pro nedestruktivní mutaci.

Předpoklady

Pokyny k instalaci

Ve Windows použijte tento konfigurační soubor WinGet k instalaci všech předpokladů. Pokud už máte něco nainstalovaného, WinGet tento krok přeskočí.

  1. Stáhněte soubor a poklikáním ho spusťte.
  2. Přečtěte si licenční smlouvu, zadejte ya po zobrazení výzvy k přijetí vyberte Enter.
  3. Pokud se na hlavním panelu zobrazí výzva řízení uživatelských účtů (UAC), povolte instalaci pokračovat.

Na jiných platformách je potřeba nainstalovat každou z těchto komponent samostatně.

  1. Stáhněte si doporučený instalační program ze stránky pro stažení sady .NET SDK a poklikáním ho spusťte. Stránka pro stažení zjistí vaši platformu a doporučí nejnovější instalační program pro vaši platformu.
  2. Stáhněte si nejnovější instalační program z domovské stránky Visual Studio Code a poklikáním ho spusťte. Tato stránka také zjistí vaši platformu a odkaz by měl být pro váš systém správný.
  3. Na stránce rozšíření C# DevKit klikněte na tlačítko Nainstalovat. Tím se otevře Visual Studio kód a zobrazí se dotaz, jestli chcete rozšíření nainstalovat nebo povolit. Vyberte "nainstalovat".

Vytvoření aplikace a prvního záznamu

Vytvořte složku pro aplikaci, spusťte dotnet new consolea otevřete vygenerovaný projekt.

Přidejte soubor s názvem DailyTemperature.csa přidejte pozici readonly record struct pro hodnoty teploty:

public readonly record struct DailyTemperature(double HighTemp, double LowTemp)
{
    public double Mean => (HighTemp + LowTemp) / 2.0;
}

Přidejte soubor s názvem Program.csa vytvořte ukázková data o teplotě:

private static DailyTemperature[] data = [
    new DailyTemperature(HighTemp: 57, LowTemp: 30), 
    new DailyTemperature(60, 35),
    new DailyTemperature(63, 33),
    new DailyTemperature(68, 29),
    new DailyTemperature(72, 47),
    new DailyTemperature(75, 55),
    new DailyTemperature(77, 55),
    new DailyTemperature(72, 58),
    new DailyTemperature(70, 47),
    new DailyTemperature(77, 59),
    new DailyTemperature(85, 65),
    new DailyTemperature(87, 65),
    new DailyTemperature(85, 72),
    new DailyTemperature(83, 68),
    new DailyTemperature(77, 65),
    new DailyTemperature(72, 58),
    new DailyTemperature(77, 55),
    new DailyTemperature(76, 53),
    new DailyTemperature(80, 60),
    new DailyTemperature(85, 66) 
];

Tato syntaxe poskytuje stručné modelování dat s neměnnou sémantikou hodnot.

Přidejte chování do struktury záznamu

Struktura DailyTemperature.cszáznamu již má vypočítanou Mean vlastnost:

public double Mean => (HighTemp + LowTemp) / 2.0;

Struktura záznamů zde funguje dobře, protože každá hodnota je malá a samostatná.

Vybudovat typy záznamů pro výpočty stupňů dnů

Note

Topné stupně a chladící stupně měří, o kolik se denní průměrná teplota liší od základní teploty (obvykle 65°F/18°C). Denostupně vytápění se hromadí během studených dnů, když je průměrná teplota pod základní hodnotou, zatímco denostupně chlazení se hromadí během teplých dnů, když je průměrná teplota nad základní hodnotou. Tyto výpočty pomáhají odhadnout spotřebu energie pro vytápění nebo chlazení budov, což je užitečné pro utility společnosti, správce budov a analýzu klimatu.

Vytvořte soubor s názvem DegreeDays.cs s hierarchií pro výpočty denostupňů pro vytápění a chlazení.

public abstract record DegreeDays(double BaseTemperature, IEnumerable<DailyTemperature> TempRecords);

public sealed record HeatingDegreeDays(double BaseTemperature, IEnumerable<DailyTemperature> TempRecords)
    : DegreeDays(BaseTemperature, TempRecords)
{
    public double DegreeDays => TempRecords.Where(s => s.Mean < BaseTemperature).Sum(s => BaseTemperature - s.Mean);
}

public sealed record CoolingDegreeDays(double BaseTemperature, IEnumerable<DailyTemperature> TempRecords)
    : DegreeDays(BaseTemperature, TempRecords)
{
    public double DegreeDays => TempRecords.Where(s => s.Mean > BaseTemperature).Sum(s => s.Mean - BaseTemperature);
}

Nyní vypočítejte součty z vaší Main metody v Program.cs:

var heatingDegreeDays = new HeatingDegreeDays(65, data);
Console.WriteLine(heatingDegreeDays);

var coolingDegreeDays = new CoolingDegreeDays(65, data);
Console.WriteLine(coolingDegreeDays);

Vygenerovaný ToString výstup je užitečný pro rychlou diagnostiku při iteraci.

Přepište PrintMembers pro přizpůsobení výstupu

Pokud výchozí výstup obsahuje příliš mnoho šumu, přepište PrintMembers v základním záznamu:

protected virtual bool PrintMembers(StringBuilder stringBuilder)
{
    stringBuilder.Append($"BaseTemperature = {BaseTemperature}");
    return true;
}

Výstup se díky přepsání zaměřuje na informace, které potřebujete.

Použití s výrazy pro nedestruktivní mutaci

with slouží k vytváření upravených kopií bez změny původního záznamu:

// Growing degree days measure warming to determine plant growing rates
var growingDegreeDays = coolingDegreeDays with { BaseTemperature = 41 };
Console.WriteLine(growingDegreeDays);

Rozšiřte tuto myšlenku na výpočet souhrnných součtů z řezů vstupních dat:

// showing moving accumulation of 5 days using range syntax
List<CoolingDegreeDays> movingAccumulation = new();
int rangeSize = (data.Length > 5) ? 5 : data.Length;
for (int start = 0; start < data.Length - rangeSize; start++)
{
    var fiveDayTotal = growingDegreeDays with { TempRecords = data[start..(start + rangeSize)] };
    movingAccumulation.Add(fiveDayTotal);
}
Console.WriteLine();
Console.WriteLine("Total degree days in the last five days");
foreach(var item in movingAccumulation)
{
    Console.WriteLine(item);
}

Tento přístup je užitečný, když potřebujete transformace, zatímco zachováváte původní hodnoty.

Další kroky