第5章 インターフェース超入門:差し替え口を作ろう🧷
この章はひとことで言うと―― **「“取り替え可能な差し込み口(口=くち)”をコードに作る回」**だよ😊🔁
いま(2026-01-16時点)の最新だと、C# 14 は .NET 10 でサポートされてるよ〜📌✨ (Microsoft Learn) (Visual Studio 2026 も .NET 10 と一緒に来てる流れだね🧡)(Microsoft for Developers)
1) インターフェースってなに?🧩

interface =「約束(ルール)」だよ🤝 「この形の差し込み口なら、これができるよね?」っていう能力の宣言✨
たとえばスマホの充電で言うと…📱🔌
- USB-C という口の形(規格)= interface
- 充電器A・充電器B(メーカー違い)= 実装クラス
つまり、使う側は「USB-C ならOK!」って思っていればよくて、メーカーを気にしなくていい😊💕
ポイント:使う側は「具体的なモノ」じゃなくて「約束(interface)」を見よう👀✨
2) なんで必要なの?(DIの前準備)💡
インターフェースがあると、こうなるよ👇
- 実装を差し替えできる🔁
- 変更が来ても、影響範囲が小さい🌱
- テストのときだけダミーにできる🧪✨
そして次章(DI)でやる「外から渡す💉」が気持ちよく決まる土台になるよ〜!
3) まずは最小で作ろう:ILogger を自作🧾✨
本物の .NET には Microsoft.Extensions.Logging の ILogger があるけど(後で触ると最高に便利✨)(Microsoft Learn)、 この章は理解が目的だから、超ミニの ILogger を自分で作るよ😊🌸
3-1) プロジェクト作成(コンソールアプリ)▶️
Visual Studio で Console App を作って、プロジェクト名を DiIoc.Ch05 とかにしておくと分かりやすいよ〜😊
4) コードを書こう✍️(差し替え体験つき🔁)
4-1) interface を作る(差し替え口🧷)
namespace DiIoc.Ch05;
public interface ILogger
{
void Log(string message);
}
ここで決めたのは **「Logできる」**っていう約束だけ😊 「どこに出すか(Console?ファイル?)」はまだ決めないよ〜✨
4-2) 実装その1:Consoleに出すやつ🖥️
namespace DiIoc.Ch05;
public sealed class ConsoleLogger : ILogger
{
public void Log(string message)
=> Console.WriteLine($"[LOG] {DateTime.Now:HH:mm:ss} {message}");
}
4-3) 実装その2:何もしないダミー🙈(テストで大活躍)
namespace DiIoc.Ch05;
public sealed class NullLogger : ILogger
{
public void Log(string message)
{
// 何もしない(でも「ILoggerとしてはOK」)
}
}
4-4) 使う側(ビジネス側)は interface だけを見る👀✨
namespace DiIoc.Ch05;
public sealed class GreetingService
{
private readonly ILogger _logger;
public GreetingService(ILogger logger)
{
_logger = logger;
}
public string CreateGreeting(string name)
{
_logger.Log($"CreateGreeting called. name={name}");
return $"こんにちは、{name}さん!";
}
}
ここが超大事💖
GreetingService は ConsoleLogger を知らないの!
知ってるのは ILogger だけ😊
4-5) 差し替え!🔁(Program.cs)
using DiIoc.Ch05;
ILogger logger = new ConsoleLogger();
// ILogger logger = new NullLogger(); // ←こっちに変えるだけでログ消える😳✨
var service = new GreetingService(logger);
Console.WriteLine(service.CreateGreeting("こみやんま"));
✅ これで体験できること
ConsoleLoggerにするとログが出る🧾NullLoggerにするとログが消える🙈- GreetingService側のコードは一切変えない🎉
この「差し替え気持ちいい〜😍」が、DIの入口だよ💉✨
5) 命名のお作法:I を付けるのは定番だよ〜🅸
.NET のガイドラインでも、interface は I を付けようってなってるよ😊 (Microsoft Learn)
だから ILogger / IClock / IEmailSender みたいになる✨
6) よくあるつまずきポイント集😵💫➡️😊
-
interfaceに詰め込みすぎる → まずは「1つの責務(できること)」に絞るのがコツ🍰
-
“データ入れ物”みたいにinterfaceを使い始める → interface は基本「ふるまい(メソッド)」の約束に向くよ🧠✨
-
「interfaceって抽象クラスと何が違うの?」 → 今は超ざっくりでOK! 「interface=約束」「class=実装」って区別できれば勝ち🏆
※ちなみに C# 8 以降は interface にデフォルト実装も書けるけど、この教材の序盤では混乱しやすいから封印でOK🙆♀️(あとで必要になったら触れよう)(Microsoft Learn)
7) ミニ課題(手を動かすと一気に定着🧠✨)📝
課題A:FileLogger を追加してみよう📁
FileLogger : ILoggerを作って、Logをファイル追記にするProgram.csでConsoleLogger↔FileLoggerを差し替え🔁
課題B:MemoryLogger を作ってみよう🧪
List<string>にログを溜める logger を作るGreetingServiceを呼んだ後、溜まったログ件数を確認✅ (テストの心が分かってくるよ〜!)
8) AI(Copilot/Codex)活用プロンプト例🤖✨
そのままコピペでOKだよ〜🧡
- 「C#で
ILoggerインターフェースとConsoleLogger/NullLoggerを最小コードで作って」 - 「
GreetingServiceがILoggerだけに依存する形にリファクタして」 - 「
FileLoggerをPath.GetTempPath()に安全に追記する実装案を出して」 - 「interfaceに責務を詰め込みすぎてないかレビューして」👀✨
9) 章末チェック✅(3つ言えたら合格💮)
- interface は **「約束」**って言える?🤝
- 実装を 差し替えできるのを体験した?🔁
- 使う側のクラスが 具体クラスを知らない形になってる?👀✨
次章予告📣💉
次はついに **DI(外から渡す)**に入るよ〜! 今日作った「差し替え口」があるから、new を中から追い出すのが気持ちよくできるはず😊✨
もしよければ、いまの理解度に合わせて👇のどれかも作ってあげるよ😊🧡
- 課題Aの
FileLoggerの完成版コード📁 - 課題Bの
MemoryLogger+軽いテストっぽい確認コード🧪 - 「interfaceと抽象クラスの違い」を“怖くない言葉”だけで整理した図解🎨