CSVファイルからStudentインスタンスを生成するサンプル
目次
この記事の目的
- CSV(カンマ区切りテキスト)形式のファイルからデータを読み取り、
- C# のクラスインスタンスにマッピングする手順を学ぶ
- 読み取ったインスタンスをコンソールに出力する
前提
- .NET 6.0 以降が動作する環境
- Visual Studio 2022 などでコンソールアプリケーションを作成できること
- 実行フォルダに「data.csv」を配置していること
プロジェクト名 StudentCsvImporterで作成します
(ヒント)実行フォルダにVisualStudioの設定で配置する方法
CSVファイルの追加
- プロジェクトを右クリック
- 追加を選択
- 新しい項目を選択

ファイルの作成
- テキストファイルを選択
- ファイル名を入力
- 追加ボタンを押下

実行フォルダにコピーするプロパティの設定

サンプルデータ(data.csv)
1,佐藤,170
2,鈴木,165
3,高橋,180
- 項目順:ID, 名前, 身長(cm)
- 行数:3 行
1. Student クラスの定義
/// <summary>
/// 学生情報を表すクラス
/// </summary>
public class Student
{
public int Id { get; }
public string Name { get; }
public int Height { get; }
public Student(int id, string name, int height)
{
Id = id;
Name = name;
Height = height;
}
public override string ToString()
{
return $"ID={Id}, 名前={Name}, 身長={Height}cm";
}
}
2. CSVファイルの読み込みとパース
以下の手順で CSV を読み込み、List<Student> を作成します。
- File.ReadAllLines で全行を取得
- string.Split(',’) でフィールドに分割
- int.TryParse で ID と身長を数値変換
- new Student(…) でインスタンス化し、リストに追加
using System;
using System.Collections.Generic;
using System.IO;
namespace StudentCsvImporter
{
class Program
{
static void Main()
{
const string filePath = "data.csv";
var students = new List<Student>();
var lines = File.ReadAllLines(filePath);
foreach (var line in lines)
{
var parts = line.Split(',');
int id = int.Parse(parts[0]);
string name = parts[1];
int height = int.Parse(parts[2]);
var student = new Student(id, name, height);
students.Add(student);
}
Console.WriteLine("=== 読み込んだ学生情報 ===");
foreach (var s in students)
{
Console.WriteLine(s);
}
}
}
}
1. 全体構成
using System;
using System.Collections.Generic;
using System.IO;
class Program
{
static void Main()
{
// … ファイル読み込み&リスト生成 …
}
}
internal class Student
{
// … プロパティ&ToString override …
}
- using System;/using System.Collections.Generic;:基本機能とジェネリックリストを使うため
- using System.IO;:ファイル入出力(File.ReadAllLines)を使うため
- Program クラス:エントリポイントとして CSV を読み込む
- Student クラス:CSV の1行分を表すデータモデル
2. Program クラスと Main メソッド
static void Main()
{
const string filePath = "data.csv";
var students = new List<Student>();
var lines = File.ReadAllLines(filePath);
foreach (var line in lines)
{
var parts = line.Split(',');
int id = int.Parse(parts[0]);
string name = parts[1];
int height = int.Parse(parts[2]);
var student = new Student(id, name, height);
students.Add(student);
}
Console.WriteLine("=== 読み込んだ学生情報 ===");
foreach (var s in students)
{
Console.WriteLine(s);
}
}
- ファイルパスとリスト初期化
- filePath に読み込む CSV ファイル名を定数として定義
- students リストを空で生成
- CSV 全行読み込み
- File.ReadAllLines(filePath) でファイルの各行を文字列配列として取得
- 行ごとのパース処理
- line.Split(',’) でカンマ区切りに分割し、parts 配列に格納
- parts[0] → ID、parts[1] → 名前、parts[2] → 身長
- int.Parse で文字列から整数へ変換
- new Student(…) で Student インスタンスを生成し、リストに追加
- 読み込み結果の表示
- Console.WriteLine(“=== 読み込んだ学生情報 ==="); に続けて
- students リストを foreach で回し、ToString() を用いて各行をコンソール出力
3. Student クラス
internal class Student
{
// 1. プロパティ(データ表現)
public int Id { get; }
public string Name { get; }
public int Height { get; }
// 2. コンストラクター(初期化)
public Student(int id, string name, int height)
{
Id = id;
Name = name;
Height = height;
}
// 3. オーバーライドしたメソッド(振る舞い)
public override string ToString()
{
return $"ID={Id}, 名前={Name}, 身長={Height}cm";
}
}
- プロパティ
- Id・Name・Height は外部から読み取りのみ可能
- コンストラクタ
- 引数で渡された id/name/height を読み取り専用プロパティにセット
- ToString のオーバーライド
- Console.WriteLine(s) の際、自動的にこの文字列が表示される
- 可読性の高い出力フォーマットを提供
4. 学習ポイント
- ファイル I/O の基本
- File.ReadAllLines によるファイル全行読み込み
- 例外処理(ファイル未検出やフォーマット異常)は入門段階では省略し、まずは動作を理解
- 文字列操作
- string.Split による簡易パーシング
- 数値変換時の例外(FormatException)も後段で扱える
- OOP によるデータモデル化
- CSV の各行を Student クラスというオブジェクトにマッピング
- ToString を活用し、出力ロジックをモデル側にカプセル化
- 責務分割
- Program.Main:ファイル読み込みとリスト管理、表示の全体フロー
- Student:1件分のデータ保持と文字列表現
この設計をベースに、たとえば「ヘッダー行のスキップ」「カンマ以外のデリミタ対応」「例外処理の追加」「List<T> でなく IEnumerable<T> や LINQ を使った一行パース」など、徐々に拡張していく練習ができます。
using System;
using System.Collections.Generic;
using System.IO;
namespace StudentCsvImporter
{
class Program
{
static void Main()
{
const string filePath = "data.csv";
var students = new List<Student>();
var lines = File.ReadAllLines(filePath);
foreach (var line in lines)
{
var parts = line.Split(',');
int id = int.Parse(parts[0]);
string name = parts[1];
int height = int.Parse(parts[2]);
var student = new Student(id, name, height);
students.Add(student);
}
Console.WriteLine("=== 読み込んだ学生情報 ===");
foreach (var s in students)
{
Console.WriteLine(s);
}
}
}
internal class Student
{
// 1. プロパティ(データ表現)
public int Id { get; }
public string Name { get; }
public int Height { get; }
// 2. コンストラクター(初期化)
public Student(int id, string name, int height)
{
Id = id;
Name = name;
Height = height;
}
// 3. オーバーライドしたメソッド(振る舞い)
public override string ToString()
{
return $"ID={Id}, 名前={Name}, 身長={Height}cm";
}
}
}
エラー処理を付加したコード
using System;
using System.Collections.Generic;
using System.IO;
class Program
{
static void Main()
{
const string filePath = "data.csv";
var students = new List<Student>();
try
{
var lines = File.ReadAllLines(filePath);
foreach (var line in lines)
{
var parts = line.Split(',');
if (parts.Length != 3)
{
Console.WriteLine($"警告: 不正な行をスキップ → \"{line}\"");
continue;
}
if (int.TryParse(parts[0], out int id)
&& int.TryParse(parts[2], out int height))
{
string name = parts[1];
var student = new Student(id, name, height);
students.Add(student);
}
else
{
Console.WriteLine($"警告: 数値変換に失敗 → \"{line}\"");
}
}
Console.WriteLine("=== 読み込んだ学生情報 ===");
foreach (var s in students)
{
Console.WriteLine(s);
}
}
catch (IOException ex)
{
Console.WriteLine($"ファイル読み込みエラー: {ex.Message}");
}
}
}
1. 全体構成
using System;
using System.Collections.Generic;
using System.IO;
class Program
{
static void Main()
{
// … CSV 読み込み&バリデーション&例外処理 …
}
}
- using System;/using System.Collections.Generic;:基本機能とジェネリックコレクションを利用
- using System.IO;:ファイル操作(File.ReadAllLines)と例外型 (IOException) を利用
- Program クラス:エントリポイントとして CSV の読み込み~出力の一連処理を担当
※Student クラスは前回の例と同様に、Id・Name・Height プロパティと ToString() を持つ想定です。
2. Main メソッドの流れ
const string filePath = "data.csv";
var students = new List<Student>();
- ファイルパス定義:定数 filePath
- 結果格納リスト:students を初期化
try
{
var lines = File.ReadAllLines(filePath);
// … 各行の処理 …
}
catch (IOException ex)
{
Console.WriteLine($"ファイル読み込みエラー: {ex.Message}");
}
- 例外ハンドリング
- ファイルが存在しない、アクセス権限エラー等の IOException をキャッチ
- キャッチ時はエラーメッセージを表示してプログラム継続
3. 各行のパース&バリデーション
foreach (var line in lines)
{
var parts = line.Split(',');
- カンマ分割:line.Split(',’) で配列化
if (parts.Length != 3)
{
Console.WriteLine($"警告: 不正な行をスキップ → \"{line}\"");
continue;
}
- 項目数チェック
- Id,Name,Height の 3 要素でなければ警告を出して次行へ
if (int.TryParse(parts[0], out int id)
&& int.TryParse(parts[2], out int height))
{
string name = parts[1];
var student = new Student(id, name, height);
students.Add(student);
}
else
{
Console.WriteLine($"警告: 数値変換に失敗 → \"{line}\"");
}
- 数値変換チェック
- TryParse を使い、ID と身長が整数であることを検証
- 成功時のみ Student を生成・追加
- 失敗時は警告メッセージを出力
4. 読み込み結果の表示
Console.WriteLine("=== 読み込んだ学生情報 ===");
foreach (var s in students)
{
Console.WriteLine(s);
}
- ヘッダー出力
- ToString() 呼び出し
- Student 側でオーバーライドした出力フォーマット(例:ID=1, 名前=山田, 身長=168cm)が利用される
5. 学習ポイント
- 例外処理による堅牢性
- try~catch で I/O エラーをキャッチし、アプリケーションの異常終了を防ぐ
- 入力データのバリデーション
- 項目数チェック → 不正行スキップ
- TryParse → 数値変換失敗時は警告出力
- ユーザーへのフィードバック
- スキップや変換失敗をコンソールに明示することで、後からログを確認しやすい
- OOP による役割分担
- Program:読み込み・検証・例外対応・一覧出力
- Student:データ保持と表示フォーマット
- 拡張・改良の余地
- ヘッダー行の自動スキップ
- セミコロンやタブ区切りへの対応
- 不正行を別ファイルへ書き出すログ機能
- JSON や XML への出力置き換え
このように、実践的なエラーチェックと例外処理を組み込むことで、CSV パーサの信頼性と保守性が大きく向上します。
4. 実行結果イメージ
=== 読み込んだ学生情報 ===
ID=1, 名前=佐藤, 身長=170cm
ID=2, 名前=鈴木, 身長=165cm
ID=3, 名前=高橋, 身長=180cm
まとめ
CSV ファイルの読み込みとクラスインスタンス生成は、業務アプリケーションでよく使われる基本パターンです。本サンプルを基に、以下のような応用にも挑戦してみてください。
- 区切り文字を変更(タブやセミコロンなど)
- 大規模データ向けに File.ReadLines を利用
- 複雑な CSV は外部ライブラリ(CsvHelper など)を導入して効率化
この流れを身につけて、より堅牢で拡張性の高いファイル I/O を実現しましょう。
参考
次のコードはいずれもまとめたコードになります
そのまま、貼り付けることができます
インスタンスのファイルへの書き出し
using System;
using System.Collections.Generic;
using System.IO;
namespace StudentCsvExporter
{
class Program
{
static void Main()
{
const string inputPath = "data.csv";
const string outputPath = "output.csv";
// 1. CSV 読み込み → List<Student> に格納
var students = new List<Student>();
var lines = File.ReadAllLines(inputPath);
foreach (var line in lines)
{
var parts = line.Split(',');
int id = int.Parse(parts[0]);
string name = parts[1];
int height = int.Parse(parts[2]);
students.Add(new Student(id, name, height));
}
// (必要に応じて students を加工)
// 2. List<Student> から書き出し用の文字列リストを作成
var outputLines = new List<string>();
foreach (var s in students)
{
// フィールドを再び CSV 形式の文字列に
outputLines.Add($"{s.Id},{s.Name},{s.Height}");
}
// 3. output.csv へ一括書き出し
File.WriteAllLines(outputPath, outputLines);
Console.WriteLine($"Saved {students.Count} records to {outputPath}");
}
}
internal class Student
{
public int Id { get; }
public string Name { get; }
public int Height { get; }
public Student(int id, string name, int height)
{
Id = id;
Name = name;
Height = height;
}
public override string ToString() =>
$"ID={Id}, 名前={Name}, 身長={Height}cm";
}
}
エラー処理あり
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
namespace StudentCsvImporter
{
class Program
{
static void Main()
{
const string inputPath = "data.csv";
const string outputPath = "output.csv";
// 1. CSV 読み込み → List<Student> 生成
var students = new List<Student>();
var lines = File.ReadAllLines(inputPath);
foreach (var line in lines)
{
var parts = line.Split(',');
if (parts.Length != 3) continue;
if (int.TryParse(parts[0], out int id)
&& int.TryParse(parts[2], out int height))
{
students.Add(new Student(id, parts[1], height));
}
}
// (必要に応じて students を加工)
// 2. 保存用文字列リストを生成
var outputLines = students
.Select(s => $"{s.Id},{s.Name},{s.Height}")
.ToArray();
// 3. CSV ファイルへ書き出し
try
{
File.WriteAllLines(outputPath, outputLines);
Console.WriteLine($"Saved {students.Count} records to {outputPath}");
}
catch (IOException ex)
{
Console.WriteLine($"書き込みエラー: {ex.Message}");
}
}
}
/// <summary>
/// 学生情報を表すクラス
/// </summary>
internal class Student
{
public int Id { get; }
public string Name { get; }
public int Height { get; }
public Student(int id, string name, int height)
{
Id = id;
Name = name;
Height = height;
}
public override string ToString() =>
$"ID={Id}, 名前={Name}, 身長={Height}cm";
}
}
訪問数 61 回, 今日の訪問数 1回
ディスカッション
コメント一覧
まだ、コメントがありません