最後のクイックスタート。
成果物
情報源
プロジェクト作成
dotnet new console -o classes cd classes
コード
- Program.cs
- BankAccount.cs
- Transaction.cs
Program.cs
using System; namespace classes { class Program { static void Main(string[] args) { var account = new BankAccount("<name>", 1000); Console.WriteLine($"Account {account.Number} was created for {account.Owner} with {account.Balance} initial balance."); 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 that the initial balances must be positive. try { var invalidAccount = new BankAccount("invalid", -55); } catch (ArgumentOutOfRangeException e) { Console.WriteLine("Exception caught creating account with negative balance"); Console.WriteLine(e.ToString()); } // 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()); } } } }
BankAccount.cs
using System; namespace classes { class BankAccount { private List<Transaction> allTransactions = new List<Transaction>(); private static int accountNumberSeed = 1234567890; public string Number { get; } public string Owner { get; set; } public decimal Balance { get { decimal balance = 0; foreach (var item in allTransactions) { balance += item.Amount; } return balance; } } public BankAccount(string name, decimal initialBalance) { this.Number = accountNumberSeed.ToString(); accountNumberSeed++; this.Owner = name; MakeDeposit(initialBalance, DateTime.Now, "Initial balance"); } 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); } } }
Transaction.cs
using System; using System.Collections.Generic; 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) { this.Amount = amount; this.Date = date; this.Notes = note; } } }
実行結果
$ dotnet run Account 1234567890 was created for <name> with 1000 initial balance. 500 600 Exception caught creating account with negative balance System.ArgumentOutOfRangeException: Amount of deposit must be positive (Parameter 'amount') at classes.BankAccount.MakeDeposit(Decimal amount, DateTime date, String note) in /tmp/work/classes/BankAccount.cs:line 35 at classes.BankAccount..ctor(String name, Decimal initialBalance) in /tmp/work/classes/BankAccount.cs:line 29 at classes.Program.Main(String[] args) in /tmp/work/classes/Program.cs:line 20 Exception caught trying to overdraw System.InvalidOperationException: Not sufficient funds for this withdrawal at classes.BankAccount.MakeWithdrawal(Decimal amount, DateTime date, String note) in /tmp/work/classes/BankAccount.cs:line 49 at classes.Program.Main(String[] args) in /tmp/work/classes/Program.cs:line 30
課題
すべてのトランザクションをログに記録する。
コード
Program.cs
以下を追記する。
Console.WriteLine(account.GetAccountHistory());
BankAccount.cs
以下を追記する。
public string GetAccountHistory() { var report = new System.Text.StringBuilder(); report.AppendLine("Date\tAmount\tNote"); foreach (var item in allTransactions) { report.AppendLine($"{item.Date.ToShortDateString()}\t{item.Amount}\t{item.Notes}"); } return report.ToString(); }
実行結果
$ dotnet run ... 2019/10/18 1000 Initial balance 2019/10/18 -500 Rent payment 2019/10/18 100 Friend paid me back
所感
今回
コピペで終わった感。自分でクラス設計を考えないと勉強できた気がしない。クラス設計の前に、アクセス修飾子、インタフェース、抽象クラスなど基礎構文について知りたかった。でもそれはクイックスタートっぽくないか。仕方ないね。
クイックスタートについて
ここまでMicrosoftのクイックスタートを辿ってきた。わかりやすくて良かったのだが、文言の不統一が気になった。
- 「配列とコレクション」と言っておきながらコレクションだけになっている
- 「クイックスタート」「チュートリアル」「レッスン」「入門」と言ったりしている
同じ概念をさすなら文言は統一してほしい。何が何やらわからなくなる。細かいことだが初学者にとっては大事。理解できるかどうかに関わる。文脈から大体わかるけど。
次回
以下のリンクがあった。
C#のバージョン
C#の最新バージョンっていくつなんだろ? 私が知っていたのは4.0で、今は8.0らしい。その間にある差を埋めねば……。サクッとググったら以下のようなリンクが出てきた。
対象環境
- Raspbierry pi 3 Model B+
- Raspbian stretch 9.0 2018-11-13 ※
- bash 4.4.12(1)-release ※
- SQLite 3.29.0 ※
- C# dotnet 3.0.100
$ uname -a Linux raspberrypi 4.19.42-v7+ #1218 SMP Tue May 14 00:48:17 BST 2019 armv7l GNU/Linux