Szkolenie
Ścieżka szkoleniowa
Użyj programu Visual Studio Code, aby tworzyć aplikacje konsolowe języka C#, które implementują tablice, pętle foreach i instrukcje if.
Ta przeglądarka nie jest już obsługiwana.
Przejdź na przeglądarkę Microsoft Edge, aby korzystać z najnowszych funkcji, aktualizacji zabezpieczeń i pomocy technicznej.
W tym samouczku utworzysz aplikację konsolową i zobaczysz podstawowe funkcje zorientowane na obiekt, które są częścią języka C#.
Za pomocą okna terminalu utwórz katalog o nazwie Classes. Utworzysz tam aplikację. Przejdź do tego katalogu i wpisz dotnet new console
polecenie w oknie konsoli. To polecenie tworzy aplikację. Otwórz plik Program.cs. Powinien on wyglądać następująco:
// See https://aka.ms/new-console-template for more information
Console.WriteLine("Hello, World!");
W tym samouczku utworzysz nowe typy reprezentujące konto bankowe. Zazwyczaj deweloperzy definiują każdą klasę w innym pliku tekstowym. Ułatwia to zarządzanie w miarę wzrostu rozmiaru programu. Utwórz nowy plik o nazwie BankAccount.cs w katalogu Classes .
Ten plik będzie zawierać definicję konta bankowego. Programowanie obiektowe organizuje kod, tworząc typy w postaci klas. Te klasy zawierają kod reprezentujący określoną jednostkę. Klasa BankAccount
reprezentuje konto bankowe. Kod implementuje określone operacje za pomocą metod i właściwości. W tym samouczku konto bankowe obsługuje następujące zachowanie:
Możesz zacząć od utworzenia podstaw klasy, która definiuje to zachowanie. Utwórz nowy plik przy użyciu polecenia File:New . Nadaj mu nazwę BankAccount.cs. Dodaj następujący kod do pliku BankAccount.cs :
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)
{
}
}
Przed rozpoczęciem przyjrzyjmy się temu, co zostało utworzone. Deklaracja namespace
umożliwia logiczne organizowanie kodu. Ten samouczek jest stosunkowo mały, więc cały kod zostanie umieszczony w jednej przestrzeni nazw.
public class BankAccount
definiuje klasę lub typ, który tworzysz. Wszystko wewnątrz klasy {
i }
, które następuje zgodnie z deklaracją klasy definiuje stan i zachowanie klasy. Istnieje pięć członków BankAccount
klasy. Pierwsze trzy są właściwościami. Właściwości to elementy danych i mogą mieć kod wymuszający walidację lub inne reguły. Ostatnie dwa są metodami. Metody to bloki kodu, które wykonują jedną funkcję. Odczytywanie nazw poszczególnych elementów członkowskich powinno dostarczyć użytkownikowi lub innemu deweloperowi wystarczające informacje, aby zrozumieć, co robi klasa.
Pierwszą funkcją implementacji jest otwarcie konta bankowego. Gdy klient otworzy konto, musi podać początkowe saldo oraz informacje o właścicielu lub właścicielach tego konta.
Utworzenie nowego obiektu BankAccount
typu oznacza zdefiniowanie konstruktora, który przypisuje te wartości. Konstruktor jest elementem członkowskim o takiej samej nazwie jak klasa. Służy do inicjowania obiektów tego typu klasy. Dodaj następujący konstruktor do BankAccount
typu . Umieść następujący kod powyżej deklaracji MakeDeposit
:
public BankAccount(string name, decimal initialBalance)
{
this.Owner = name;
this.Balance = initialBalance;
}
Powyższy kod identyfikuje właściwości obiektu konstruowanego przez dołączenie kwalifikatora this
. Ten kwalifikator jest zwykle opcjonalny i pomijany. Można również napisać:
public BankAccount(string name, decimal initialBalance)
{
Owner = name;
Balance = initialBalance;
}
this
Kwalifikator jest wymagany tylko wtedy, gdy zmienna lokalna lub parametr ma taką samą nazwę jak to pole lub właściwość. this
Kwalifikator zostanie pominięty w pozostałej części tego artykułu, chyba że jest to konieczne.
Konstruktory są wywoływane podczas tworzenia obiektu przy użyciu polecenia new
. Zastąp wiersz Console.WriteLine("Hello World!");
w Program.cs następującym kodem (zastąp <name>
ciąg nazwą):
using Classes;
var account = new BankAccount("<name>", 1000);
Console.WriteLine($"Account {account.Number} was created for {account.Owner} with {account.Balance} initial balance.");
Uruchommy to, co zostało utworzone do tej pory. Jeśli używasz programu Visual Studio, wybierz pozycję Rozpocznij bez debugowania z menu Debugowanie . Jeśli używasz wiersza polecenia, wpisz dotnet run
katalog, w którym utworzono projekt.
Czy zauważyłeś, że numer konta jest pusty? Nadszedł czas, aby to naprawić. Numer konta należy przypisać podczas konstruowania obiektu. Ale nie powinno to być obowiązkiem rozmówców, aby go stworzyć. Kod BankAccount
klasy powinien wiedzieć, jak przypisać nowe numery kont. Prostym sposobem jest rozpoczęcie od 10-cyfrowej liczby. Zwiększ go po utworzeniu każdego nowego konta. Na koniec zapisz numer bieżącego konta podczas konstruowania obiektu.
Dodaj deklarację składową do BankAccount
klasy. Umieść następujący wiersz kodu po nawiasie klamrowym {
otwierającym na początku BankAccount
klasy:
private static int s_accountNumberSeed = 1234567890;
Element accountNumberSeed
jest elementem członkowskim danych. private
Jest to , co oznacza, że dostęp do niego można uzyskać tylko za pomocą kodu wewnątrz BankAccount
klasy. Jest to sposób oddzielenia obowiązków publicznych (takich jak posiadanie numeru konta) od implementacji prywatnej (sposób generowania numerów kont). Jest to również static
element , co oznacza, że jest współużytkowany BankAccount
przez wszystkie obiekty. Wartość zmiennej niestatycznej jest unikatowa dla każdego wystąpienia BankAccount
obiektu. Jest accountNumberSeed
to pole, w związku z private static
czym ma s_
prefiks zgodnie z konwencjami nazewnictwa języka C#. Oznaczanie s
i _
oznaczanie static
private
pola. Dodaj następujące dwa wiersze do konstruktora, aby przypisać numer konta. Umieść je po wierszu z napisem this.Balance = initialBalance
:
Number = s_accountNumberSeed.ToString();
s_accountNumberSeed++;
Wpisz dotnet run
, aby wyświetlić wyniki.
Klasa konta bankowego musi zaakceptować depozyty i wypłaty, aby działały prawidłowo. Zaimplementujmy depozyty i wypłaty, tworząc dziennik każdej transakcji dla konta. Śledzenie każdej transakcji ma kilka zalet w stosunku do prostego aktualizowania salda dla każdej transakcji. Historia może służyć do inspekcji wszystkich transakcji i zarządzania dziennymi saldami. Obliczenie salda z historii wszystkich transakcji w razie potrzeby gwarantuje, że wszelkie błędy w jednej transakcji, które zostały naprawione, zostaną poprawnie odzwierciedlone w saldu na następnej obliczeniach.
Zacznijmy od utworzenia nowego typu reprezentującego transakcję. Transakcja jest prostym typem, który nie ma żadnych obowiązków. Potrzebuje kilku właściwości. Utwórz nowy plik o nazwie Transaction.cs. Dodaj do niej następujący kod:
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;
}
}
Teraz dodajmy List<T> obiekt BankAccount
do Transaction
klasy . Dodaj następującą deklarację po konstruktorze w pliku BankAccount.cs :
private List<Transaction> _allTransactions = new List<Transaction>();
Teraz poprawnie obliczmy element Balance
. Bieżące saldo można znaleźć, sumując wartości wszystkich transakcji. Ponieważ kod jest obecnie, możesz uzyskać tylko początkowe saldo konta, więc trzeba będzie zaktualizować Balance
właściwość. Zastąp wiersz public decimal Balance { get; }
w BankAccount.cs następującym kodem:
public decimal Balance
{
get
{
decimal balance = 0;
foreach (var item in _allTransactions)
{
balance += item.Amount;
}
return balance;
}
}
W tym przykładzie przedstawiono ważny aspekt właściwości. Teraz obliczysz saldo, gdy inny programista o wartość. Obliczenia wyliczają wszystkie transakcje i udostępniają sumę jako bieżące saldo.
Następnie zaimplementuj MakeDeposit
metody i MakeWithdrawal
. Te metody wymuszają dwie ostatnie reguły: początkowe saldo musi być dodatnie, a każde wycofanie nie może utworzyć ujemnego salda.
Te reguły wprowadzają pojęcie wyjątków. Standardowym sposobem wskazywania, że metoda nie może pomyślnie ukończyć swojej pracy, jest zgłoszenie wyjątku. Typ wyjątku i skojarzony z nim komunikat opisują błąd. W tym miejscu metoda zgłasza wyjątek, MakeDeposit
jeśli kwota depozytu nie jest większa niż 0. Metoda MakeWithdrawal
zgłasza wyjątek, jeśli kwota wypłaty nie jest większa niż 0, lub jeśli zastosowanie wypłaty spowoduje ujemne saldo. Dodaj następujący kod po deklaracji _allTransactions
listy:
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);
}
Instrukcja throw
zgłasza wyjątek. Wykonanie bieżącego bloku kończy się i przeniesienie kontrolek do pierwszego pasującego catch
bloku znalezionego w stosie wywołań. Dodasz catch
blok, aby przetestować ten kod nieco później.
Konstruktor powinien uzyskać jedną zmianę, aby dodawał początkową transakcję, zamiast aktualizować saldo bezpośrednio. Ponieważ już napisałeś metodę MakeDeposit
, wywołaj ją z konstruktora. Gotowy konstruktor powinien wyglądać następująco:
public BankAccount(string name, decimal initialBalance)
{
Number = s_accountNumberSeed.ToString();
s_accountNumberSeed++;
Owner = name;
MakeDeposit(initialBalance, DateTime.Now, "Initial balance");
}
DateTime.Now jest właściwością zwracającą bieżącą datę i godzinę. Przetestuj ten kod, dodając kilka depozytów i wypłat w metodzie Main
, postępując zgodnie z kodem, który tworzy nowy BankAccount
kod :
account.MakeWithdrawal(500, DateTime.Now, "Rent payment");
Console.WriteLine(account.Balance);
account.MakeDeposit(100, DateTime.Now, "Friend paid me back");
Console.WriteLine(account.Balance);
Następnie przetestuj, czy przechwytujesz warunki błędu, próbując utworzyć konto z ujemnym saldem. Dodaj następujący kod po właśnie dodanym kodzie:
// 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;
}
Instrukcja służy try-catch
do oznaczania bloku kodu, który może zgłaszać wyjątki i przechwytywać oczekiwane błędy. Możesz użyć tej samej techniki, aby przetestować kod, który zgłasza wyjątek dla ujemnego salda. Dodaj następujący kod przed deklaracją invalidAccount
w metodzie Main
:
// 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());
}
Zapisz plik i wpisz dotnet run
, aby go wypróbować.
Aby ukończyć ten samouczek, możesz napisać GetAccountHistory
metodę, która tworzy string
obiekt dla historii transakcji. Dodaj tę metodę do BankAccount
typu:
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();
}
Historia używa StringBuilder klasy do formatowania ciągu zawierającego jeden wiersz dla każdej transakcji. Kod formatowania ciągów został już wcześniej wyświetlony w tych samouczkach. Jeden nowy znak to \t
. Powoduje to wstawienie karty w celu sformatowania danych wyjściowych.
Dodaj ten wiersz, aby przetestować go w Program.cs:
Console.WriteLine(account.GetAccountHistory());
Uruchom program, aby wyświetlić wyniki.
Jeśli utkniesz, możesz zobaczyć źródło tego samouczka w naszym repozytorium GitHub.
Możesz kontynuować pracę z samouczkiem dotyczącym programowania obiektowego .
Więcej informacji na temat tych pojęć można uzyskać w następujących artykułach:
Opinia o produkcie .NET
.NET to projekt typu open source. Wybierz link, aby przekazać opinię:
Szkolenie
Ścieżka szkoleniowa
Użyj programu Visual Studio Code, aby tworzyć aplikacje konsolowe języka C#, które implementują tablice, pętle foreach i instrukcje if.