Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
In deze zelfstudie bouwt u een consoletoepassing en ziet u de eenvoudige objectgeoriënteerde functies die deel uitmaken van de C#-taal.
Vereisten
- De nieuwste .NET SDK-
- Visual Studio Code-editor
- De C# DevKit
Installatie-instructies
Op Windows wordt dit WinGet-configuratiebestand gebruikt om alle vereisten te installeren. Als u al iets hebt geïnstalleerd, slaat WinGet die stap over.
- Download het bestand en dubbelklik erop om het uit te voeren.
- Lees de gebruiksrechtovereenkomst, typ yen selecteer Enter wanneer u wordt gevraagd om te accepteren.
- Als u een knipperende UAC-prompt (User Account Control) krijgt op de taakbalk, staat u de installatie toe om door te gaan.
Op andere platforms moet u elk van deze onderdelen afzonderlijk installeren.
- Download het aanbevolen installatieprogramma op de downloadpagina van de .NET SDK en dubbelklik erop om het uit te voeren. De downloadpagina detecteert uw platform en raadt het meest recente installatieprogramma voor uw platform aan.
- Download het meest recente installatieprogramma van de Visual Studio Code startpagina en dubbelklik erop om het uit te voeren. Deze pagina detecteert ook uw platform en de koppeling moet juist zijn voor uw systeem.
- Klik op de knop Installeren op de pagina C# DevKit extensie. Hiermee opent u Visual Studio-code en wordt gevraagd of u de extensie wilt installeren of inschakelen. Selecteer 'installeren'.
Uw toepassing maken
Maak met behulp van een terminalvenster een map met de naam Klassen. Daar bouwt u uw toepassing. Ga naar die map en typ dotnet new console
in het consolevenster. Met deze opdracht maakt u uw toepassing. Open Program.cs. Dit ziet er als volgt uit:
// See https://aka.ms/new-console-template for more information
Console.WriteLine("Hello, World!");
In deze zelfstudie gaat u nieuwe typen maken die een bankrekening vertegenwoordigen. Ontwikkelaars definiëren doorgaans elke klasse in een ander tekstbestand. Hierdoor wordt het eenvoudiger om te beheren naarmate een programma groter wordt. Maak een nieuw bestand met de naam BankAccount.cs in de map Klassen.
Dit bestand bevat de definitie van een bankrekening. Objectgeoriënteerd programmeren ordent code door typen te maken in de vorm van klassen. Deze klassen bevatten de code die een specifieke entiteit vertegenwoordigt. De BankAccount
klasse vertegenwoordigt een bankrekening. De code implementeert specifieke bewerkingen via methoden en eigenschappen. In deze zelfstudie ondersteunt de bankrekening dit gedrag:
- Het heeft een getal van 10 cijfers dat de bankrekening uniek identificeert.
- Deze bevat een tekenreeks waarin de naam of namen van de eigenaren worden opgeslagen.
- Het saldo kan worden opgehaald.
- Het accepteert deposito's.
- Het accepteert intrekkingen.
- Het aanvankelijke saldo moet positief zijn.
- Intrekkingen kunnen geen negatief saldo opleveren.
Het type bankrekening definiëren
U kunt beginnen met het maken van de basisbeginselen van een klasse die dat gedrag definieert. Maak een nieuw bestand met de opdracht File:New . Noem het BankAccount.cs. Voeg de volgende code toe aan uw BankAccount.cs-bestand :
namespace Classes;
public class BankAccount
{
public string Number { get; }
public string Owner { get; set; }
public decimal Balance { get; }
public void MakeDeposit(decimal amount, DateTime date, string note)
{
}
public void MakeWithdrawal(decimal amount, DateTime date, string note)
{
}
}
Voordat we verdergaan, gaan we eens kijken wat u hebt gebouwd. De namespace
declaratie biedt een manier om uw code logisch te ordenen. Deze zelfstudie is relatief klein, dus je plaatst alle code in één naamruimte.
public class BankAccount
definieert de klasse of het type dat u maakt. Alles binnen de {
en }
die volgt op de klassedeclaratie definieert de status en het gedrag van de klasse. Er zijn vijf leden van de BankAccount
klas. De eerste drie zijn eigenschappen. Eigenschappen zijn gegevenselementen en kunnen code bevatten waarmee validatie of andere regels worden afgedwongen. De laatste twee zijn methoden. Methoden zijn codeblokken die één functie uitvoeren. Het lezen van de namen van de leden zou voldoende informatie moeten geven aan jou of een andere ontwikkelaar om te begrijpen wat de klasse doet.
Een nieuw account openen
De eerste functie die moet worden geïmplementeerd, is het openen van een bankrekening. Wanneer een klant een account opent, moet deze een eerste saldo en informatie over de eigenaar of eigenaren van dat account opgeven.
Het maken van een nieuw object van het BankAccount
type betekent het definiëren van een constructor die deze waarden toewijst. Een constructor is een lid met dezelfde naam als de klasse. Het wordt gebruikt om objecten van dat klassetype te initialiseren. Voeg de volgende constructor toe aan het BankAccount
type. Plaats de volgende code boven de declaratie van MakeDeposit
:
public BankAccount(string name, decimal initialBalance)
{
this.Owner = name;
this.Balance = initialBalance;
}
De voorgaande code identificeert de eigenschappen van het object dat wordt samengesteld door de this
kwalificatie in te delen. Die kwalificatie is meestal optioneel en weggelaten. U kunt ook het volgende hebben geschreven:
public BankAccount(string name, decimal initialBalance)
{
Owner = name;
Balance = initialBalance;
}
De this
kwalificatie is alleen vereist wanneer een lokale variabele of parameter dezelfde naam heeft als dat veld of die eigenschap. De this
kwalificatie wordt in de rest van dit artikel weggelaten, tenzij dit nodig is.
Constructors worden aangeroepen wanneer u een object maakt met behulp van new
. Vervang de regel Console.WriteLine("Hello World!");
in Program.cs door de volgende code (vervang <name>
door uw naam):
using Classes;
var account = new BankAccount("<name>", 1000);
Console.WriteLine($"Account {account.Number} was created for {account.Owner} with {account.Balance} initial balance.");
Laten we eens uitvoeren wat u tot nu toe hebt gebouwd. Als u Visual Studio gebruikt, selecteert u Start zonder foutopsporing in het menu Foutopsporing . Als u de opdrachtregel gebruikt, typt u dotnet run
in de map waar u uw project hebt gemaakt.
Hebt u gemerkt dat het accountnummer leeg is? Het is tijd om dat op te lossen. Het accountnummer moet worden toegewezen wanneer het object is gecreëerd. Maar het zou niet de verantwoordelijkheid van de oproeper moeten zijn om dit te maken. De BankAccount
klassecode moet weten hoe nieuwe accountnummers moeten worden toegewezen. Een eenvoudige manier is om te beginnen met een getal van 10 cijfers. Verhoog het wanneer elk nieuw account wordt gemaakt. Sla ten slotte het huidige rekeningnummer op wanneer een object wordt samengesteld.
Voeg een liddeclaratie toe aan de BankAccount
klasse. Plaats de volgende regel code na de openingsaccolade aan het begin van de {
class:
private static int s_accountNumberSeed = 1234567890;
Het accountNumberSeed
is een gegevenslid.
private
Dit betekent dat het alleen toegankelijk is via code in de BankAccount
klasse. Het is een manier om de openbare verantwoordelijkheden (zoals een rekeningnummer) te scheiden van de privé-implementatie (hoe rekeningnummers worden gegenereerd). Het is ook static
, wat betekent dat het wordt gedeeld door alle BankAccount
objecten. De waarde van een niet-statische variabele is uniek voor elk exemplaar van het BankAccount
object. Het accountNumberSeed
is een private static
veld en heeft dus het s_
voorvoegsel volgens C#-naamconventies. Het s
veld dat aangeeft static
en _
aangeeft private
. Voeg de volgende twee regels toe aan de constructor om het rekeningnummer toe te wijzen. Plaats ze na de regel met de tekst this.Balance = initialBalance
:
Number = s_accountNumberSeed.ToString();
s_accountNumberSeed++;
Typ dotnet run
om de resultaten weer te geven.
Stortingen en intrekkingen maken
Uw bankrekeningklasse moet deposito's en intrekkingen accepteren om correct te kunnen werken. Laten we stortingen en intrekkingen implementeren door een logboek te maken van elke transactie voor het account. Het bijhouden van elke transactie heeft enkele voordelen ten opzichte van het bijwerken van het saldo voor elke transactie. De geschiedenis kan worden gebruikt om alle transacties te controleren en dagelijkse saldi te beheren. Het berekenen van het saldo uit de geschiedenis van alle transacties wanneer dat nodig is, zorgt ervoor dat eventuele fouten in één transactie die zijn opgelost, correct worden weergegeven in het saldo voor de volgende berekening.
Laten we beginnen met het maken van een nieuw type om een transactie weer te geven. De transactie is een eenvoudig type dat geen verantwoordelijkheden heeft. Het heeft een paar eigenschappen nodig. Maak een nieuw bestand met de naam Transaction.cs. Voeg de volgende code toe eraan:
namespace Classes;
public class Transaction
{
public decimal Amount { get; }
public DateTime Date { get; }
public string Notes { get; }
public Transaction(decimal amount, DateTime date, string note)
{
Amount = amount;
Date = date;
Notes = note;
}
}
Nu gaan we een List<T> van Transaction
objecten aan de BankAccount
klasse toevoegen. Voeg de volgende declaratie toe na de constructor in uw BankAccount.cs-bestand :
private List<Transaction> _allTransactions = new List<Transaction>();
Laten we nu de Balance
correct berekenen. Het huidige saldo kan worden gevonden door de waarden van alle transacties op te tellen. Zoals de code momenteel is, kunt u alleen het eerste saldo van het account ophalen, dus moet u de Balance
eigenschap bijwerken. Vervang de regel public decimal Balance { get; }
in BankAccount.cs door de volgende code:
public decimal Balance
{
get
{
decimal balance = 0;
foreach (var item in _allTransactions)
{
balance += item.Amount;
}
return balance;
}
}
In dit voorbeeld ziet u een belangrijk aspect van eigenschappen. U rekent nu het saldo op wanneer een andere programmeur om de waarde vraagt. Uw berekening bevat alle transacties en levert de som als het huidige saldo.
Implementeer vervolgens de MakeDeposit
en MakeWithdrawal
methoden. Met deze methoden worden de laatste twee regels afgedwongen: het oorspronkelijke saldo moet positief zijn en elke intrekking mag geen negatief saldo creëren.
Deze regels introduceren het concept van uitzonderingen. De standaardmethode waarmee wordt aangegeven dat een methode het werk niet kan voltooien, is door een uitzondering te genereren. Het type uitzondering en het bijbehorende bericht beschrijven de fout. Hier genereert de MakeDeposit
methode een uitzondering als het bedrag van de storting niet groter is dan 0. De MakeWithdrawal
methode genereert een uitzondering als het opnamebedrag niet groter is dan 0 of als het toepassen van de opname resulteert in een negatief saldo. Voeg de volgende code toe na de declaratie van de _allTransactions
lijst:
public void MakeDeposit(decimal amount, DateTime date, string note)
{
if (amount <= 0)
{
throw new ArgumentOutOfRangeException(nameof(amount), "Amount of deposit must be positive");
}
var deposit = new Transaction(amount, date, note);
_allTransactions.Add(deposit);
}
public void MakeWithdrawal(decimal amount, DateTime date, string note)
{
if (amount <= 0)
{
throw new ArgumentOutOfRangeException(nameof(amount), "Amount of withdrawal must be positive");
}
if (Balance - amount < 0)
{
throw new InvalidOperationException("Not sufficient funds for this withdrawal");
}
var withdrawal = new Transaction(-amount, date, note);
_allTransactions.Add(withdrawal);
}
De throw
instructiegenereert een uitzondering. Uitvoering van het huidige blok eindigt, en de controle gaat naar het eerste overeenkomende catch
blok dat in de aanroepstack wordt gevonden. U voegt later een catch
blok toe om deze code te testen.
De constructor moet één wijziging krijgen, zodat er een initiële transactie wordt toegevoegd in plaats van het saldo rechtstreeks bij te werken. Omdat u de MakeDeposit
-methode al hebt geschreven, roept u deze aan vanuit uw constructor. De voltooide constructor moet er als volgt uitzien:
public BankAccount(string name, decimal initialBalance)
{
Number = s_accountNumberSeed.ToString();
s_accountNumberSeed++;
Owner = name;
MakeDeposit(initialBalance, DateTime.Now, "Initial balance");
}
DateTime.Now is een eigenschap die de huidige datum en tijd retourneert. Test deze code door enkele stortingen en intrekkingen toe te voegen aan uw Main
methode, met behulp van de code waarmee een nieuwe BankAccount
wordt gemaakt:
account.MakeWithdrawal(500, DateTime.Now, "Rent payment");
Console.WriteLine(account.Balance);
account.MakeDeposit(100, DateTime.Now, "Friend paid me back");
Console.WriteLine(account.Balance);
Test vervolgens of u foutcondities kunt opvangen door te proberen een account met een negatief saldo aan te maken. Voeg de volgende code toe na de voorgaande code die u zojuist hebt toegevoegd:
// Test that the initial balances must be positive.
BankAccount invalidAccount;
try
{
invalidAccount = new BankAccount("invalid", -55);
}
catch (ArgumentOutOfRangeException e)
{
Console.WriteLine("Exception caught creating account with negative balance");
Console.WriteLine(e.ToString());
return;
}
U gebruikt de try-catch
instructie om een codeblok te markeren dat uitzonderingen kan genereren en om die fouten te ondervangen die u verwacht. U kunt dezelfde techniek gebruiken om de code te testen die een uitzondering genereert voor een negatief saldo. Voeg de volgende code toe vóór de declaratie van invalidAccount
in uw Main
methode:
// Test for a negative balance.
try
{
account.MakeWithdrawal(750, DateTime.Now, "Attempt to overdraw");
}
catch (InvalidOperationException e)
{
Console.WriteLine("Exception caught trying to overdraw");
Console.WriteLine(e.ToString());
}
Sla het bestand op en typ dotnet run
om het uit te proberen.
Uitdaging: alle transacties registreren
Als u deze zelfstudie wilt voltooien, kunt u de GetAccountHistory
methode schrijven waarmee een string
voor de transactiegeschiedenis wordt gemaakt. Voeg deze methode toe aan het BankAccount
type:
public string GetAccountHistory()
{
var report = new System.Text.StringBuilder();
decimal balance = 0;
report.AppendLine("Date\t\tAmount\tBalance\tNote");
foreach (var item in _allTransactions)
{
balance += item.Amount;
report.AppendLine($"{item.Date.ToShortDateString()}\t{item.Amount}\t{balance}\t{item.Notes}");
}
return report.ToString();
}
De geschiedenis gebruikt de StringBuilder klasse om een tekenreeks op te maken die één regel voor elke transactie bevat. Je hebt de tekenreeksopmaakcode eerder in deze handleidingen gezien. Eén nieuw teken is \t
. Hiermee wordt een tabblad ingevoegd om de uitvoer op te maken.
Voeg deze regel toe om deze te testen in Program.cs:
Console.WriteLine(account.GetAccountHistory());
Voer uw programma uit om de resultaten te bekijken.
Volgende stappen
Als u vastloopt, kunt u de bron voor deze zelfstudie zien in onze GitHub-opslagplaats.
U kunt doorgaan met de zelfstudie objectgeoriënteerd programmeren .
Meer informatie over deze concepten vindt u in deze artikelen: