Skip to content

第9章 クラスを使いこなそう

この章では、.NET に用意されている便利なクラスを使って、C# の標準機能を 調べながら使う練習 をします。

第 7 章では Employee などのクラスを自分で作成し、第 8 章では DateTime.NowMath.Max など、クラス名から直接使える機能を学習しました。

実際の開発では、自分でクラスを作るだけでなく、.NET が用意しているクラスを呼び出して使う ことの方が多くなります。 次のような処理は、ほぼすべて .NET の標準クラスで実現できます。

文字列の長さを調べる
文字列に特定の文字が含まれるか調べる
文字列をカンマで区切って分割する
小数を四捨五入する
現在の日付を取得して指定形式で表示する
テキストファイルに書き込む
テキストファイルを読み込む

この章では、string の便利な機能、Math クラスの数値計算、DateTime の日付処理、File クラスのファイル操作を扱いながら、名前空間using ディレクティブ の役割も整理します。


この章でできるようになること

Section titled “この章でできるようになること”

この章を終えると、次のことができるようになります。

  • 名前空間と using ディレクティブの役割を説明できる
  • 暗黙的 using で省略されている using を理解できる
  • string の代表的なプロパティ・メソッドを使える(LengthContainsSubstringReplaceTrimSplitJoinIsNullOrEmpty など)
  • Math の代表的な静的メソッドを使える(RoundCeilingFloorPow など)
  • DateTime で日付の作成・加算・差の計算ができる
  • 日付を指定した形式の文字列に変換できる
  • File クラスでテキストファイルを書き込み・読み込みできる
  • File.Exists でファイルの存在を確認できる
  • 標準クラスを調べながら使う姿勢を身に付ける

項目内容
開発環境Visual Studio 2022
プロジェクト種類コンソール アプリ
対象フレームワーク.NET 8
ソリューション名Chapter09
プロジェクト名Ch09_UsefulClasses

csproj の Nullable は disable に変更してください

プロジェクト作成後、Ch09_UsefulClasses.csproj を開き、<Nullable>disable</Nullable> に変更してください。

詳しい手順は、第 1 章「1-1 プロジェクトを作成する」を参照してください。


作業を始める前に、次の内容を確認してください。

  • クラスを作成し、別ファイルに分けて書ける(第 7 章)
  • 静的メソッド・静的プロパティを使える(第 8 章)
  • プロパティとメソッドの違いを説明できる
  • ファイルスコープ namespace を書ける
  • 第 8 章の内容を Git に提出済みである

名前空間(namespace)とは、クラスを分類するための「入れ物」です。 .NET には、数千ものクラスが用意されており、それらは目的別に名前空間で分類されています。

名前空間内容
SystemConsoleStringDateTimeMath など、最も基本的なクラス
System.IOFileDirectory など、ファイル操作のクラス
System.Collections.GenericList<T>Dictionary<K,V> などのコレクション
System.LinqLINQ(集合操作)

これまで自作してきたクラスにも namespace を付けてきました(namespace Ch07_Class; など)。 名前空間は クラスの「住所」 のようなものと考えると分かりやすいです。


完全修飾名と using ディレクティブ

Section titled “完全修飾名と using ディレクティブ”

Console クラスは System 名前空間に含まれています。完全な書き方(完全修飾名)は次のとおりです。

System.Console.WriteLine("こんにちは");

毎回これを書くのは長いので、ファイル先頭に using ディレクティブを書きます。

using System;
Console.WriteLine("こんにちは");

using System; を書くと、「System 名前空間にあるクラスは、名前空間を省略して書ける」という意味になります。


これまでのサンプルコードでは、using System;一度も書いていません。 それでも Console.WriteLineDateTime.Now が使えてきました。

これは、.NET 8 のプロジェクトで 暗黙的 using(<ImplicitUsings>enable</ImplicitUsings>)が有効になっているためです。 暗黙的 using が有効だと、次の名前空間が 自動で取り込まれます

名前空間含まれる主なクラス
SystemConsoleStringDateTimeMath
System.IOFileDirectory
System.Collections.GenericList<T>Dictionary<K,V>
System.LinqLINQ 関連
System.Threading.TasksTask

そのため、この研修のコードでは using System;using System.IO; を書く必要がありません。

補足:暗黙的 using がない場合

古いプロジェクトや、<ImplicitUsings>disable</ImplicitUsings> の場合は、ファイル先頭に using System; などを 明示的に書く必要があります。 現場のプロジェクトを読むときは、ファイル先頭の using 一覧を見て「どの名前空間が使われているか」を確認しましょう。


同じ名前のクラスでも、名前空間が違えば別物として扱えます。

Sales.Employee
→ 営業システム用の Employee クラス
Training.Employee
→ 研修管理用の Employee クラス

どちらも Employee ですが、名前空間が違うので区別できます。 大きなシステムでは、機能ごとに名前空間を分けて、クラス名の衝突を防ぎます。


これまで、文字列を string 型で扱ってきました。

string employeeName = "山田二郎";

string には、文字列を扱うための 便利なプロパティとメソッド が用意されています。


Program.cs
namespace Ch09_UsefulClasses;
internal class Program
{
static void Main(string[] args)
{
string employeeName = "山田二郎";
Console.WriteLine($"氏名:{employeeName}");
Console.WriteLine($"文字数:{employeeName.Length}");
}
}

実行結果:

氏名:山田二郎
文字数:4

Lengthプロパティ なので、() は付けません。


Contains:含まれているか判定する

Section titled “Contains:含まれているか判定する”
Program.cs
namespace Ch09_UsefulClasses;
internal class Program
{
static void Main(string[] args)
{
string email = "yamada@example.com";
if (email.Contains("@"))
{
Console.WriteLine("@が含まれています。");
}
else
{
Console.WriteLine("@が含まれていません。");
}
}
}

実行結果:

@が含まれています。

Contains は、指定した文字列が含まれていれば true、なければ false を返します。


StartsWith / EndsWith:先頭・末尾を判定する

Section titled “StartsWith / EndsWith:先頭・末尾を判定する”

Contains の仲間で、指定した文字列で始まるか / 終わるか を判定します。

string fileName = "report.csv";
Console.WriteLine(fileName.StartsWith("report")); // 先頭が report か
Console.WriteLine(fileName.EndsWith(".csv")); // 末尾が .csv か
Console.WriteLine(fileName.EndsWith(".txt"));

実行結果:

True
True
False

ファイルの拡張子チェックや、メールアドレスのドメイン判定などに使います。


string employeeCode = "EMP1001";
string prefix = employeeCode.Substring(0, 3); // 0番目から3文字
string number = employeeCode.Substring(3); // 3番目から最後まで
Console.WriteLine($"接頭辞:{prefix}");
Console.WriteLine($"番号:{number}");

実行結果:

接頭辞:EMP
番号:1001
E M P 1 0 0 1
0 1 2 3 4 5 6 ← インデックス

Substring(開始位置, 文字数) または Substring(開始位置) のように使います。

注意:範囲外を指定するとエラー

文字列の長さを超える位置を指定すると、実行時にエラー(ArgumentOutOfRangeException)になります。 code.Substring(3, 4) のように、文字列の長さに対して十分かどうか確認しましょう。


string message = "C#を勉強しています。";
string replaced = message.Replace("勉強", "学習");
Console.WriteLine(message);
Console.WriteLine(replaced);

実行結果:

C#を勉強しています。
C#を学習しています。

Replace は、元の文字列を変更せず、置き換え後の新しい文字列を返しますmessage 自身は変わらない点に注意してください。


ToUpper / ToLower:大文字・小文字に揃える

Section titled “ToUpper / ToLower:大文字・小文字に揃える”
string command = "Add";
Console.WriteLine(command.ToUpper());
Console.WriteLine(command.ToLower());

実行結果:

ADD
add

入力されたコマンドを小文字に統一してから判定する、といった用途に便利です。

string input = Console.ReadLine();
string normalized = input.ToLower();

string input = " yamada ";
string trimmed = input.Trim();
Console.WriteLine($"[{input}]");
Console.WriteLine($"[{trimmed}]");

実行結果:

[ yamada ]
[yamada]

ユーザー入力の前後に余計な空白が入ってしまうケースに有効です。


IsNullOrEmpty / IsNullOrWhiteSpace:空かどうかを判定する

Section titled “IsNullOrEmpty / IsNullOrWhiteSpace:空かどうかを判定する”

入力チェックでは「文字列が空かどうか」を頻繁に判定します。 string.IsNullOrEmptynull または空文字列("") のときに true を返します。

string input1 = "";
string input2 = "山田";
Console.WriteLine(string.IsNullOrEmpty(input1)); // True
Console.WriteLine(string.IsNullOrEmpty(input2)); // False

IsNullOrWhiteSpace は、それに加えて 空白だけの文字列(スペースやタブ)も true とみなします。

string input3 = " "; // 空白だけ
Console.WriteLine(string.IsNullOrEmpty(input3)); // False(空白も文字とみなす)
Console.WriteLine(string.IsNullOrWhiteSpace(input3)); // True

補足:string クラスから直接呼ぶ静的メソッド

これらは input.IsNullOrEmpty() ではなく、string.IsNullOrEmpty(input) のように string クラス名から呼び出す静的メソッド(第 8 章)です。 引数が null でも安全に判定できるので、入力チェックの定番として使われます。

利用例:名前が未入力なら警告する。

string name = Console.ReadLine();
if (string.IsNullOrWhiteSpace(name))
{
Console.WriteLine("名前を入力してください。");
}

1 つの文字列を、区切り文字で 複数の文字列(配列)に分割 します。 CSV(カンマ区切り)のデータを 1 行ずつ読むときなどに使う、とても出番の多いメソッドです。

string csvLine = "1001,山田,二郎,総務";
string[] columns = csvLine.Split(',');
Console.WriteLine(columns[0]); // 1001
Console.WriteLine(columns[1]); // 山田
Console.WriteLine(columns[2]); // 二郎
Console.WriteLine(columns[3]); // 総務
Console.WriteLine($"列数:{columns.Length}");

実行結果:

1001
山田
二郎
総務
列数:4

Split(',')string[](文字列の配列) を返します。第 6 章で学んだ配列の知識がそのまま使えます。

補足:分割した値は文字列のまま

columns[0]"1001" という 文字列 です。数値として計算に使いたい場合は、int.Parse(columns[0])int.TryParse(第 15 章)で数値に変換します。


Split の逆で、配列やリストを区切り文字でつないで 1 つの文字列にします。 CSV の 1 行を組み立てて書き出すときなどに使います。

string[] columns = { "1001", "山田", "二郎", "総務" };
string csvLine = string.Join(",", columns);
Console.WriteLine(csvLine);

実行結果:

1001,山田,二郎,総務

string.Join(区切り文字, 配列) のように、string クラス名から呼び出す静的メソッドです。


メンバー種類内容返す型
Lengthプロパティ文字数int
Contains(s)メソッドs を含むかbool
StartsWith(s)メソッドs で始まるかbool
EndsWith(s)メソッドs で終わるかbool
Substring(start, length)メソッド一部を取り出すstring
Replace(old, new)メソッド置き換えるstring
ToUpper() / ToLower()メソッド大文字/小文字に変換string
Trim()メソッド前後の空白を取り除くstring
Split(c)メソッド区切り文字で分割string[]
string.Join(c, 配列)静的メソッド区切り文字でつなぐstring
string.IsNullOrEmpty(s)静的メソッドnull または空文字列かbool
string.IsNullOrWhiteSpace(s)静的メソッドnull・空・空白だけかbool

文字列を加工する SubstringReplaceToUpperToLowerTrim は、新しい文字列を返し、元の文字列は変更しませんContainsStartsWithEndsWithIsNullOrEmptybool(真偽値)Split配列 を返します。 string.Joinstring.IsNullOrEmpty 系は、string クラス名から呼び出す 静的メソッド(第 8 章)である点に注意してください。


Math クラスには、数値計算用の 静的メソッド が用意されています。 第 8 章では Math.MaxMath.Min を扱いました。この章では、もう少し便利なメソッドを見ていきます。


Program.cs
namespace Ch09_UsefulClasses;
internal class Program
{
static void Main(string[] args)
{
double average = 82.6666667;
double rounded = Math.Round(average, 1);
Console.WriteLine($"元の値:{average}");
Console.WriteLine($"丸めた値:{rounded}");
}
}

実行結果:

元の値:82.6666667
丸めた値:82.7

Math.Round(値, 桁数) で、指定した小数位で四捨五入できます。


Ceiling / Floor:切り上げ・切り捨て

Section titled “Ceiling / Floor:切り上げ・切り捨て”
double value = 12.3;
Console.WriteLine(Math.Ceiling(value)); // 切り上げ → 13
Console.WriteLine(Math.Floor(value)); // 切り捨て → 12
メソッド意味
Math.Round(値, 桁数)四捨五入
Math.Ceiling(値)切り上げ(整数値へ)
Math.Floor(値)切り捨て(整数値へ)

double result = Math.Pow(2, 3); // 2 の 3 乗
Console.WriteLine(result);

実行結果:

8

Math.Pow(底, 指数) で、底を指数回掛け合わせた値を返します(戻り値は double)。


利用例:平均点を丸めて表示する

Section titled “利用例:平均点を丸めて表示する”
Program.cs
namespace Ch09_UsefulClasses;
internal class Program
{
static void Main(string[] args)
{
int[] scores = { 80, 75, 90, 68, 85 };
int total = 0;
foreach (int score in scores)
{
total += score;
}
double average = (double)total / scores.Length;
double rounded = Math.Round(average, 1);
Console.WriteLine($"平均点:{rounded}");
}
}

実行結果:

平均点:79.6

特定の日付を表すオブジェクトは、new DateTime(年, 月, 日) で作成します。

DateTime trainingStartDate = new DateTime(2026, 5, 18);
Console.WriteLine(trainingStartDate);

実行結果:

2026/05/18 0:00:00

時刻まで指定したい場合は new DateTime(2026, 5, 18, 9, 30, 0) のように書きます。


DateTime startDate = new DateTime(2026, 5, 18);
DateTime endDate = startDate.AddDays(27);
Console.WriteLine($"開始日:{startDate}");
Console.WriteLine($"終了予定日:{endDate}");

実行結果:

開始日:2026/05/18 0:00:00
終了予定日:2026/06/14 0:00:00

AddDays と同じように AddMonthsAddYearsAddHours などもあります。


2 つの日付の差は、引き算で求められます。戻り値は TimeSpan(時間の長さを表す型)です。

DateTime startDate = new DateTime(2026, 5, 18);
DateTime endDate = new DateTime(2026, 6, 14);
TimeSpan period = endDate - startDate;
Console.WriteLine($"日数:{period.Days}");

実行結果:

日数:27日

TimeSpanDays プロパティで日数を取得できます。


DateTimeToString(書式) で、好きな形式の文字列に変換できます。

DateTime date = new DateTime(2026, 5, 18, 9, 30, 0);
Console.WriteLine(date.ToString("yyyy/MM/dd"));
Console.WriteLine(date.ToString("yyyy年MM月dd日"));
Console.WriteLine(date.ToString("yyyy/MM/dd HH:mm"));

実行結果:

2026/05/18
2026年05月18日
2026/05/18 09:30

書式表示例意味
yyyy2026西暦 4 桁
MM05月 2 桁(0 埋め)
M5月(0 埋めなし)
dd18日 2 桁(0 埋め)
HH09時 2 桁(24 時制)
mm30分 2 桁
ss00秒 2 桁

業務アプリでは、画面表示用・ファイル名用・ログ出力用など、用途に応じて書式を使い分けます。


利用例:ファイル名に日付を入れる

Section titled “利用例:ファイル名に日付を入れる”
DateTime today = DateTime.Today;
string fileName = $"sales_{today.ToString("yyyyMMdd")}.txt";
Console.WriteLine(fileName);

実行結果(例):

sales_20260518.txt

yyyyMMdd のように区切り文字なしの書式を使うと、ファイル名に使いやすい文字列が作れます。


File クラスは、テキストファイルの読み書きに使う静的クラスです。 System.IO 名前空間に含まれていますが、暗黙的 using で省略済み なので、そのまま File.〇〇 の形で使えます。


社員名の一覧をテキストファイルに書き込みます。

Program.cs
namespace Ch09_UsefulClasses;
internal class Program
{
static void Main(string[] args)
{
string[] employeeNames =
{
"山田二郎",
"佐藤昭夫",
"山口洋子"
};
File.WriteAllLines("employee_names.txt", employeeNames);
Console.WriteLine("ファイルを書き込みました。");
}
}

実行結果:

ファイルを書き込みました。

employee_names.txt というファイルが作成されます。

補足:ファイルの作成場所

ファイル名だけを指定した場合、ファイルはプログラムの 実行フォルダ に作成されます。 Visual Studio から実行した場合、プロジェクトフォルダではなく bin\Debug\net8.0\ フォルダに作られます。 ファイルが見つからないときは、このフォルダを探してみてください。


Program.cs
namespace Ch09_UsefulClasses;
internal class Program
{
static void Main(string[] args)
{
string[] lines = File.ReadAllLines("employee_names.txt");
foreach (string line in lines)
{
Console.WriteLine(line);
}
}
}

実行結果:

山田二郎
佐藤昭夫
山口洋子

File.ReadAllLines は、ファイルの全行を string[] として返します。


File.Exists でファイルの存在を確認する

Section titled “File.Exists でファイルの存在を確認する”

ファイルが存在しない状態で ReadAllLines を実行するとエラーになります。 そこで、File.Exists で先に存在を確認します。

Program.cs
namespace Ch09_UsefulClasses;
internal class Program
{
static void Main(string[] args)
{
string filePath = "employee_names.txt";
if (File.Exists(filePath))
{
string[] lines = File.ReadAllLines(filePath);
foreach (string line in lines)
{
Console.WriteLine(line);
}
}
else
{
Console.WriteLine("ファイルが見つかりません。");
}
}
}

メソッド内容
File.WriteAllLines(path, lines)配列をファイルに書き込む(上書き)
File.WriteAllText(path, text)文字列をファイルに書き込む(上書き)
File.ReadAllLines(path)ファイルを string[] として読み込む
File.ReadAllText(path)ファイルを 1 つの文字列として読み込む
File.AppendAllText(path, text)ファイルに追記する
File.Exists(path)ファイルが存在するか調べる

利用例:ログファイルに追記する

Section titled “利用例:ログファイルに追記する”
Program.cs
namespace Ch09_UsefulClasses;
internal class Program
{
static void Main(string[] args)
{
string timeStamp = DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss");
string logText = $"{timeStamp} アプリを実行しました。";
File.AppendAllText("app.log", logText + Environment.NewLine);
Console.WriteLine("ログを追記しました。");
}
}

Environment.NewLine は、環境に応じた改行コードを表します(Windows なら \r\n)。

実行結果:

ログを追記しました。

app.log の内容(2 回実行した場合):

2026/05/18 09:30:00 アプリを実行しました。
2026/05/18 09:35:12 アプリを実行しました。

ファイル操作で起こりやすい問題

Section titled “ファイル操作で起こりやすい問題”
ファイルが存在しない
保存先フォルダが存在しない
同じ名前のファイルを上書きしてしまう
他のアプリがファイルを開いている

これらに本格的に対処するには 例外処理 が必要です。例外処理は後の章で扱います。


つまずき原因対応
using の意味が分からない名前空間との関係が曖昧「名前空間を省略して書ける」と覚える
using System; を書かないと動かないと思う暗黙的 using の存在を知らない.NET 8 の暗黙的 using で省略されている
Length() を付けてしまうプロパティとメソッドの混同Length はプロパティ
Replace で元の変数が変わらない戻り値を受け取っていないs = s.Replace(...); のように代入する
Substring で実行時エラー文字列の長さを超える位置を指定している範囲を確認する
Split の結果を数値として計算できない分割後も文字列のままint.Parse / int.TryParse で変換する
IsNullOrEmptys.IsNullOrEmpty() と書く静的メソッドをインスタンスから呼んでいるstring.IsNullOrEmpty(s) のようにクラス名から呼ぶ
DateTime.Now() と書いてしまうプロパティに () を付けているNow はプロパティ
日付の書式が思った通りにならない書式記号を間違えているyyyyMMdd の大文字小文字に注意
ファイルが見つからない実行フォルダを誤解しているbin\Debug\net8.0\ を確認
File.ReadAllLines でエラーファイルが存在しないFile.Exists で先に確認
Math.Round の戻り値の桁数が思った通りでない第 2 引数を指定していないMath.Round(値, 1) のように桁数を指定

  • 名前空間とは何かを説明できる
  • using ディレクティブの役割を説明できる
  • 暗黙的 using の意味を説明できる
  • stringLengthContainsSubstringReplaceToLowerTrim を使える
  • stringSplitJoinIsNullOrEmptyIsNullOrWhiteSpace を使える
  • Math.RoundMath.CeilingMath.FloorMath.Pow を使える
  • new DateTime(年, 月, 日) で日付を作成できる
  • AddDays で日付を加算できる
  • 2 つの日付の差を TimeSpan で求められる
  • ToString("yyyy/MM/dd") で日付の表示形式を指定できる
  • File.WriteAllLines でファイルを書き込める
  • File.ReadAllLines でファイルを読み込める
  • File.Exists でファイルの存在を確認できる
  • File.AppendAllText でファイルに追記できる

研修の進め方によっては、隣の人またはチーム内で説明確認を行います。

次の内容を、自分の言葉で説明してください。

  1. 名前空間は何のためにありますか。
  2. using System; を書かなくても Console.WriteLine が使えるのはなぜですか。
  3. LengthContains() の書き方の違いは何ですか。
  4. Math.Round(82.666, 1) は何を返しますか。
  5. DateTime.NowDateTime.Today の違いは何ですか。
  6. File.WriteAllLinesFile.ReadAllLines は、それぞれ何をするメソッドですか。
  7. ファイルを読み込む前に File.Exists を使う理由は何ですか。

説明するときは、完全な答えでなくても構いません。 自分の言葉で説明しようとすることが大切です。


この章の演習課題に取り組みます。

本章では タイマー方式 を試験導入します。次の 3 段階で進めてください。

段階時間内容
① 準備10 分(目安)上の「ペア確認」と、これから取り組む課題(仕様)の読み込み。ペアや講師に質問してよい
② ソロ作業30 分(タイマーで計測)一人で課題に取り組む。タイマーが鳴ったら、完成・未完成にかかわらず作業を止めて提出する
③ チーム時間講師が指定する発表開始時刻までチーム内でコードレビューを行い、発表者を決める。実装の続行も可。時間配分はチームで管理する

第 9 章は .NET 標準ライブラリの使い方 が中心で、新しいロジックは少なめですが、課題数が多く File 入出力でファイル作成も伴います。ソロ作業は 30 分 をとっています。準備フェーズの終わりに講師が号令をかけ、そこからタイマーを開始します。 評価対象はタイマー時点で提出されたコードです(タイマー後に書き足した分は評価には含まれません)。 発表開始時刻は厳守 です。チーム時間中も、その時刻が来たら全員手を止めて発表に移ります。

演習の進め方の詳細は、付録A「演習の進め方」 を参照してください。


課題はソリューション Kadai09 の中に作成してください。 課題ごとに別のプロジェクトを作成 し、指定されたプロジェクト名を使います。

課題必須/発展プロジェクト名作成する主なファイル
課題 9-1必須Kd09_01_StringPracticeProgram.cs
課題 9-2必須Kd09_02_DateTimeFormatProgram.cs
課題 9-3必須Kd09_03_FileReadWriteProgram.cs
課題 9-4発展Kd09_04_CommandJudgeProgram.cs
課題 9-5発展Kd09_05_TrainingScheduleProgram.cs
課題 9-6発展Kd09_06_AppLogProgram.cs

フォルダ構成は次のようになります。

Kadai09/ ← 課題用ソリューションフォルダ
Kadai09.sln
Kd09_01_StringPractice/
Kd09_02_DateTimeFormat/
Kd09_03_FileReadWrite/
Kd09_04_CommandJudge/
Kd09_05_TrainingSchedule/
Kd09_06_AppLog/

補足:ソリューションに複数のプロジェクトを追加する方法

最初の課題で Kadai09 ソリューションと Kd09_01_StringPractice プロジェクトを同時に作成します。

2 つ目以降の課題は、ソリューションエクスプローラーで Kadai09 を右クリックし、追加新しいプロジェクト から追加します。


以下は、本章のすべての課題に共通する作業です。各課題の本文には繰り返し書きません。

作業内容参照
プロジェクト作成時の設定最上位レベルのステートメントを使用しない」にチェック第 1 章 1-1
csproj の編集<Nullable>disable</Nullable> に変更第 1 章 1-1
namespace の書き方ファイルスコープ形式(namespace XXX;)で書く第 7 章 冒頭
ファイルを保存して実行Ctrl + S で保存 → F5 で実行第 1 章 1-2

特に 2 つ目以降のプロジェクト(Kd09_02_DateTimeFormat など)も、新規追加するたびに csproj の Nullable を disable に変更する 必要があります。

Program.cs を自動生成すると、ブロック形式の namespace プロジェクト名 { ... } で作られます(例:課題 9-1 なら namespace Kd09_01_StringPractice { ... })。本章でもファイルスコープ形式に統一するため、生成後に namespace Kd09_01_StringPractice; のように ; 形式に書き換えてください。

提出ルール(タイマー方式)

  • 準備フェーズの後、講師の号令で 30 分のタイマー をスタートします
  • タイマーが鳴ったら、完成・未完成にかかわらず手を止め、その場で git addgit commitgit push を行います
  • これがこの演習の 唯一の提出 です。タイマー後も実装を続けて構いませんが、書き足した分は評価対象には含まれません

コミットメッセージの形式:

Chapter09 タイマー提出: <どの課題まで完成> / <詰まったポイント>

例:

  • Chapter09 タイマー提出: 9-1〜9-2完成、9-3は途中 / File.WriteAllLines の使い方で詰まった
  • Chapter09 タイマー提出: 9-1〜9-3完成、発展未着手 / 特になし
  • Chapter09 タイマー提出: 9-1完成、9-2の途中 / DateTime の書式指定子が思い出せない

「どこまでできたか」「詰まったポイント」は短くて構いません。順調なときも「特になし」と明示 してください(順調さの証拠になります)。

提出方法:Git が使えないときはサーバへコピー

Git の状態によっては、講師から「今回は push ではなくサーバへのフォルダコピーで提出」と指示が出ることがあります。その場合は、push の代わりに Kadai09 フォルダをサーバの所定の場所へコピーして提出してください(コピー手順は別途案内済みのとおり)。

このとき コミットメッセージが残せない ため、代わりに 提出メモ.txt というテキストファイルを提出先に作成します。コピーが終わってから、次の手順で作成してください。

  1. Kadai09 フォルダをコピーした、サーバ上の自分の名前のフォルダをエクスプローラーで開く
  2. 何もないところで右クリック → 新規作成 → テキスト ドキュメント を選ぶ
  3. ファイル名を 提出メモ.txt に変更する
  4. ダブルクリックで開き、次の内容を書いて保存する
どこまで完成: 9-1〜9-3完成、発展未着手
詰まったポイント: 特になし

書く内容は、コミットメッセージに書くはずだった「どこまで完成したか」「詰まったポイント」と同じです。順調なときも「詰まったポイント: 特になし」と明示 してください。

タイマー後のチーム時間の使い方

タイマー後、講師が指定する 発表開始時刻 までがチーム時間です。チーム内で次の 3 つを自由に管理してください。

  • コードレビュー:他のメンバーの commit を読んで、気づいたことを共有する
  • 発表者の選出:発表開始時刻に、チームから 1 人が要点を発表できるよう、誰が話すかを決めておく
  • 実装の続行(任意):途中だった課題を続けても構いません(提出後の追加分は評価対象外ですが、理解を深める意義はあります)

どの順番で進めるか、何分ずつ使うかはチームの判断です。ただし 発表開始時刻は厳守 です。その時刻までにレビューと発表者選出を必ず終わらせてください。


まずは、全員が必須課題に取り組んでください。


課題 9-1 文字列を分解・判定する

Section titled “課題 9-1 文字列を分解・判定する”

社員コードとメールアドレスから情報を取り出すプログラムを作成してください。

次の値を変数に代入して使います。

string employeeCode = "EMP1001";
string email = "yamada@example.com";

次の内容を表示してください。

  1. 社員コードの先頭 3 文字(接頭辞)
  2. 社員コードの 4 文字目以降(番号)
  3. メールアドレスの文字数
  4. メールアドレスに @ が含まれているかどうか(true/false)

実行結果例:

接頭辞:EMP
番号:1001
メール文字数:18
@含む:True

条件:

  • SubstringLengthContains を使う
  • 文字列補間 $"..." で表示する

課題 9-2 今日の日付を表示する

Section titled “課題 9-2 今日の日付を表示する”

DateTime.Today を使って、今日の日付を 3 つの形式で表示してください。

実行結果例(2026/05/18 に実行した場合):

2026/05/18
2026年05月18日
20260518

条件:

  • DateTime.Today を使う
  • ToString("yyyy/MM/dd") を使う
  • ToString("yyyy年MM月dd日") を使う
  • ToString("yyyyMMdd") を使う

課題 9-3 社員名一覧をファイルに書き出して読み戻す

Section titled “課題 9-3 社員名一覧をファイルに書き出して読み戻す”

社員名 3 名分を employee_names.txt に書き込み、書き込んだファイルを読み込んで表示してください。

書き込む内容:

山田二郎
佐藤昭夫
山口洋子

実行結果例:

ファイルを書き込みました。
--- 読み込み結果 ---
山田二郎
佐藤昭夫
山口洋子

条件:

  • string[] を使う
  • File.WriteAllLines で書き込む
  • File.Exists でファイルの存在を確認する
  • File.ReadAllLines で読み込み、foreach で表示する

必須課題が終わった人は、発展課題に取り組んでください。 発展課題からは、仕様だけが提示されます。実装方法は自分で考えてください。


ユーザーから入力されたコマンドを 小文字に統一してから 判定するプログラムを作成してください。

仕様

  • Console.ReadLine でコマンドを 1 行受け取る
  • 入力を Trim で前後の空白を取り除き、ToLower で小文字に変換する
  • 次のいずれかに応じて表示する(switch 文を使う)
コマンド(小文字後)表示
add登録処理を行います
list一覧表示を行います
exit終了します
それ以外不明なコマンドです

実行例:

コマンドを入力してください: ADD
登録処理を行います

課題 9-5 研修スケジュールを作成する

Section titled “課題 9-5 研修スケジュールを作成する”

以下の仕様で、研修日程を計算して表示するプログラムを作成してください。

仕様

  • 研修開始日:new DateTime(2026, 5, 18)
  • 研修期間:27 日後が終了予定日
  • 表示する内容:
    • 開始日(yyyy/MM/dd)
    • 終了予定日(yyyy/MM/dd)
    • 研修日数(終了予定日 − 開始日 = 何日)

実行結果例:

開始日:2026/05/18
終了予定日:2026/06/14
研修日数:27日

条件:

  • AddDays を使う
  • TimeSpanDays プロパティを使う
  • ToString("yyyy/MM/dd") を使う

プログラム実行時の日時を app.log に追記するプログラムを作成してください。 複数回実行すると、行が増えていくようにします。

仕様

  • 現在日時(DateTime.Now)を yyyy/MM/dd HH:mm:ss 形式で取得する
  • "{日時} アプリを実行しました。" という形式のログを app.log に追記する
  • 改行には Environment.NewLine を使う
  • 書き込み後、File.ReadAllLines で全行読み込み、行数を表示する

実行結果例(3 回目の実行時):

ログを追記しました。
現在のログ行数:3行

app.log の内容例:

2026/05/18 09:30:00 アプリを実行しました。
2026/05/18 09:35:12 アプリを実行しました。
2026/05/18 09:40:45 アプリを実行しました。

  • プログラムを Visual Studio から実行できる
  • stringLengthContainsSubstring などを使えている
  • Length() を付けていない
  • Math.Round で桁数を指定できている
  • DateTime を作成・加算・差分計算できている
  • 日付を指定した形式で表示できている
  • File.WriteAllLines または File.WriteAllText でファイルを書き込めている
  • File.ReadAllLines または File.ReadAllText でファイルを読み込めている
  • File.Exists でファイルの存在を確認できている
  • インデントが整っている
  • 課題を提出した(Git の commitpush、または講師指示があれば Kadai09 フォルダをサーバへコピーし、提出先フォルダに 提出メモ.txt を作成)

タイマーが鳴ったら、第 9 章の課題プロジェクト群(Kadai09 ソリューション)をその場で Git に提出します。

Terminal window
git status
git add .
git commit -m "Chapter09 タイマー提出: <どこまで完成> / <詰まったポイント>"
git push

実行例:

Terminal window
git commit -m "Chapter09 タイマー提出: 9-1〜9-2完成、9-3は途中 / File.WriteAllLines の使い方で詰まった"

Git の詳しい操作は、付録 C「Git のインストールと提出ルール」 を参照してください。

コミットメッセージの形式は、本章冒頭「演習課題 > 提出ルール(タイマー方式)」を参照してください。

サーバへのコピーで提出する場合

講師から指示があった場合は、push の代わりに Kadai09 フォルダをサーバへコピーして提出します。コピー後、提出先(サーバ上の自分の名前のフォルダ)をエクスプローラーで開き、右クリック → 新規作成 → テキスト ドキュメント で 提出メモ.txt を作って「どこまで完成」「詰まったポイント」を書いてください。詳しくは本章冒頭「演習課題 > 提出方法:Git が使えないときはサーバへコピー」を参照してください。

補足:出力ファイルの扱い

ファイル操作の課題では、作成された .txt.log ファイルが bin\Debug\net8.0\ フォルダに残ります。 これらを Git に含めるかどうかは、研修の指示に従ってください。 通常、bin/ フォルダは .gitignore で除外されるため、自動的に提出対象外になることが多いです。


この章では、.NET が用意している便利なクラスを使いました。 主な内容は次のとおりです。

  • 名前空間はクラスを分類する入れ物、using で名前空間の指定を省略できる
  • 暗黙的 using により、SystemSystem.IO などは自動で取り込まれている
  • string には LengthContainsSubstringReplaceToLowerTrim などの便利な機能がある
  • stringSplit(分割)・Join(連結)・IsNullOrEmpty/IsNullOrWhiteSpace(空判定)は、CSV 処理や入力チェックでよく使う
  • Math には RoundCeilingFloorPow などの数値計算メソッドがある
  • DateTime は日付の作成・加算・差分計算・形式変換ができる
  • TimeSpan は時間の長さを表す型で、日付の引き算の結果として得られる
  • File クラスで、テキストファイルの書き込み・読み込み・追記・存在確認ができる
  • 標準クラスは「自分で作らずに調べて使う」ことが基本

次章では、クラスについてさらに掘り下げます

メソッドのオーバーロード(同名メソッドの複数定義)、省略可能な引数、コンストラクター、プロパティの実装方法などを学び、クラスをより実践的に使えるようにしていきます。

第 7 章から第 9 章で身に付けた基礎を土台に、次章ではクラスの設計力を伸ばしていきます。