Console.WriteLine
.NET標準のコンソール出力メソッド。設定不要で即座に利用可能な最もシンプルなロギング手段。開発・デバッグ段階での迅速な出力確認に適しているが、本番環境では機能が限定的。プロトタイピングに最適。
ライブラリ
Console.WriteLine
概要
Console.WriteLineは、.NET標準のコンソール出力メソッドで、C#開発における最もシンプルなロギング手段です。設定不要で即座に利用可能な最も基本的なログ出力機能を提供し、開発・デバッグ段階での迅速な出力確認に最適。文字列補間、フォーマット文字列、合成フォーマット機能をサポートし、プロトタイピングや学習段階での利用に理想的です。本格的なアプリケーション開発では機能が限定的なため、専用ロギングライブラリへの移行が強く推奨されます。
詳細
Console.WriteLineは、System名前空間の標準メソッドとして.NET Framework初期から提供されており、2025年でも学習・プロトタイピング段階での利用は不変です。C# 11以降の文字列補間機能($"")、生文字列リテラル、複数ドル記号による複雑なフォーマッティングと完全に統合されており、現代的なC#構文と高い親和性を持ちます。Visual Studio統合開発環境での出力ウィンドウ表示、デバッグセッション中のリアルタイム確認が可能。.NET初学者や簡単なコンソールアプリケーションでの使用が継続される一方、本格的なアプリケーション開発ではMicrosoft.Extensions.Logging、Serilog、NLog等の専用ライブラリへの移行が業界標準となっています。
主な特徴
- .NET標準搭載: 追加インストール不要の即座利用
- 文字列補間対応: C# 11以降の最新構文完全サポート
- フォーマット機能: 複合フォーマットと文字列補間の柔軟な使い分け
- Visual Studio統合: 開発環境での直接的な出力確認
- 軽量: ゼロオーバーヘッドの単純なI/O操作
- 学習コスト最小: C#初学者に最適な導入ツール
メリット・デメリット
メリット
- .NETエコシステムでの標準的地位と学習コストの完全な欠如
- 設定・初期化不要による即座の利用開始と開発効率向上
- C#文字列補間機能との完全統合による現代的な記述体験
- Visual Studio開発環境での優れた統合性とデバッグ体験
- 軽量な実装による他のライブラリへの影響皆無
- プロトタイピングと概念実証での理想的なシンプルさ
デメリット
- 本番環境での機能制限とログ管理・監視機能の完全な欠如
- ログレベル、フィルタリング、カテゴリ分類機能の不在
- ファイル出力、データベース記録、外部サービス連携の不可能
- 同期I/O操作による高負荷時のパフォーマンス制約
- 構造化ログ、JSON出力、分析ツール統合の限界
- エンタープライズ要件に対する機能不足
参考ページ
- Console.WriteLine Method (System) | Microsoft Learn
- String interpolation - C# | Microsoft Learn
- Composite formatting - .NET | Microsoft Learn
書き方の例
基本的な文字列出力
using System;
class Program
{
static void Main()
{
// 基本的な文字列出力
Console.WriteLine("Hello, World!");
Console.WriteLine("アプリケーションが開始されました");
// 変数の出力
string userName = "田中太郎";
int userAge = 30;
bool isActive = true;
Console.WriteLine(userName);
Console.WriteLine(userAge);
Console.WriteLine(isActive);
// 複数行の出力
Console.WriteLine("第1行目");
Console.WriteLine("第2行目");
Console.WriteLine("第3行目");
// 空行の出力
Console.WriteLine();
Console.WriteLine("空行の後のメッセージ");
}
}
文字列補間(String Interpolation)
using System;
class Program
{
static void Main()
{
// 基本的な文字列補間
string name = "田中太郎";
int age = 30;
decimal salary = 85000.50m;
DateTime joinDate = new DateTime(2020, 4, 1);
Console.WriteLine($"名前: {name}");
Console.WriteLine($"年齢: {age}歳");
Console.WriteLine($"給与: {salary:C}");
Console.WriteLine($"入社日: {joinDate:yyyy年MM月dd日}");
// 複雑な式の埋め込み
Console.WriteLine($"来年の年齢: {age + 1}歳");
Console.WriteLine($"経験年数: {DateTime.Now.Year - joinDate.Year}年");
Console.WriteLine($"ステータス: {(age >= 30 ? "シニア" : "ジュニア")}");
// フォーマット指定子の使用
double value = 123.456789;
Console.WriteLine($"小数点2桁: {value:F2}");
Console.WriteLine($"パーセント表示: {0.85:P}");
Console.WriteLine($"指数表記: {value:E}");
Console.WriteLine($"16進数: {255:X}");
// 条件演算子との組み合わせ
int score = 85;
Console.WriteLine($"成績: {score}点 ({(score >= 80 ? "優秀" : score >= 60 ? "合格" : "不合格")})");
// メソッド呼び出しの埋め込み
Console.WriteLine($"現在時刻: {DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss")}");
Console.WriteLine($"ランダム値: {new Random().Next(1, 100)}");
}
}
C# 11以降の生文字列リテラル
using System;
class Program
{
static void Main()
{
// 基本的な生文字列リテラル
string sqlQuery = """
SELECT u.Name, u.Age, d.DepartmentName
FROM Users u
INNER JOIN Departments d ON u.DepartmentId = d.Id
WHERE u.IsActive = 1
ORDER BY u.Name
""";
Console.WriteLine("SQL Query:");
Console.WriteLine(sqlQuery);
// 補間を使った生文字列リテラル
string tableName = "Users";
int minAge = 25;
string dynamicQuery = $$"""
SELECT *
FROM {{tableName}}
WHERE Age >= {{minAge}}
AND IsActive = 1
""";
Console.WriteLine($"Dynamic Query:");
Console.WriteLine(dynamicQuery);
// JSONテンプレートの例
string userName = "田中太郎";
int userId = 123;
string jsonTemplate = $$"""
{
"userId": {{userId}},
"userName": "{{userName}}",
"settings": {
"theme": "dark",
"language": "ja"
},
"permissions": ["read", "write"]
}
""";
Console.WriteLine("JSON Template:");
Console.WriteLine(jsonTemplate);
// 複雑なテキストフォーマット
string projectName = "WebApp";
string version = "1.2.3";
DateTime buildDate = DateTime.Now;
string buildInfo = $$"""
┌─────────────────────────────────────┐
│ ビルド情報 │
├─────────────────────────────────────┤
│ プロジェクト: {{projectName}} │
│ バージョン: {{version}} │
│ ビルド日時: {{buildDate:yyyy/MM/dd HH:mm}} │
└─────────────────────────────────────┘
""";
Console.WriteLine(buildInfo);
}
}
複合フォーマット(Composite Formatting)
using System;
class Program
{
static void Main()
{
// 基本的な複合フォーマット
string name = "田中太郎";
int age = 30;
decimal salary = 85000.50m;
Console.WriteLine("名前: {0}, 年齢: {1}, 給与: {2:C}", name, age, salary);
// 位置指定子の重複使用
Console.WriteLine("{0}さんは{1}歳です。{0}さんの給与は{2:C}です。", name, age, salary);
// 幅指定とアライメント
Console.WriteLine("名前: {0,-20} 年齢: {1,3} 給与: {2,12:C}", name, age, salary);
// より複雑なフォーマット例
var employees = new[]
{
new { Name = "田中太郎", Age = 30, Salary = 85000.50m },
new { Name = "佐藤花子", Age = 28, Salary = 78000.00m },
new { Name = "鈴木次郎", Age = 35, Salary = 92000.75m }
};
Console.WriteLine("社員一覧:");
Console.WriteLine("{0,-15} {1,5} {2,12}", "名前", "年齢", "給与");
Console.WriteLine(new string('-', 35));
foreach (var emp in employees)
{
Console.WriteLine("{0,-15} {1,5} {2,12:C}", emp.Name, emp.Age, emp.Salary);
}
// カスタムフォーマットプロバイダー
var japaneseProvider = new System.Globalization.CultureInfo("ja-JP");
Console.WriteLine("日本語ロケール: {0:C}", 123456.78, japaneseProvider);
// 日付時刻のフォーマット
DateTime now = DateTime.Now;
Console.WriteLine("現在時刻: {0:yyyy年MM月dd日 HH時mm分ss秒}", now);
Console.WriteLine("短い日付: {0:d}", now);
Console.WriteLine("長い日付: {0:D}", now);
Console.WriteLine("ISO形式: {0:yyyy-MM-ddTHH:mm:ss}", now);
}
}
デバッグとトラブルシューティング
using System;
using System.Collections.Generic;
using System.Diagnostics;
class Program
{
static void Main()
{
// 条件付きコンパイル
#if DEBUG
Console.WriteLine("デバッグモードで実行中");
#endif
// デバッグ用の詳細出力
var userData = new
{
Id = 123,
Name = "田中太郎",
Email = "[email protected]",
CreatedAt = DateTime.Now.AddDays(-30)
};
Console.WriteLine("=== ユーザーデータ ===");
Console.WriteLine($"ID: {userData.Id}");
Console.WriteLine($"名前: {userData.Name}");
Console.WriteLine($"メールアドレス: {userData.Email}");
Console.WriteLine($"作成日: {userData.CreatedAt:yyyy/MM/dd}");
// 例外情報の出力
try
{
int divisor = 0;
int result = 10 / divisor;
}
catch (Exception ex)
{
Console.WriteLine("例外が発生しました:");
Console.WriteLine($" 種類: {ex.GetType().Name}");
Console.WriteLine($" メッセージ: {ex.Message}");
Console.WriteLine($" スタックトレース:");
Console.WriteLine(ex.StackTrace);
}
// 処理時間の測定
var stopwatch = Stopwatch.StartNew();
// 時間のかかる処理のシミュレーション
System.Threading.Thread.Sleep(100);
stopwatch.Stop();
Console.WriteLine($"処理時間: {stopwatch.ElapsedMilliseconds}ms");
// メモリ使用量の表示
long memoryBefore = GC.GetTotalMemory(false);
Console.WriteLine($"使用メモリ: {memoryBefore:N0} bytes");
// コレクションの内容表示
var numbers = new List<int> { 1, 2, 3, 4, 5 };
Console.WriteLine($"配列の内容: [{string.Join(", ", numbers)}]");
// オブジェクトの詳細表示
var person = new Person { Name = "田中太郎", Age = 30 };
Console.WriteLine($"Person object: {person}");
}
}
class Person
{
public string Name { get; set; }
public int Age { get; set; }
public override string ToString()
{
return $"Name={Name}, Age={Age}";
}
}
高度なフォーマッティングテクニック
using System;
using System.Globalization;
using System.Text;
class Program
{
static void Main()
{
// 数値フォーマットの詳細制御
decimal value = 1234567.89m;
Console.WriteLine("=== 数値フォーマット ===");
Console.WriteLine($"通貨: {value:C}");
Console.WriteLine($"固定小数点: {value:F2}");
Console.WriteLine($"指数: {value:E2}");
Console.WriteLine($"数値: {value:N2}");
Console.WriteLine($"パーセント: {0.1234:P2}");
Console.WriteLine($"ゼロ埋め: {123:D8}");
Console.WriteLine($"16進数: {255:X4}");
// カスタム数値フォーマット
Console.WriteLine($"カスタム1: {value:#,##0.00}");
Console.WriteLine($"カスタム2: {value:¥#,##0}");
Console.WriteLine($"条件付き: {-123:正の値;負の値;ゼロ}");
// 日付時刻の詳細フォーマット
DateTime dateTime = new DateTime(2025, 6, 24, 14, 30, 45);
Console.WriteLine("\n=== 日付時刻フォーマット ===");
Console.WriteLine($"標準: {dateTime}");
Console.WriteLine($"短い日付: {dateTime:d}");
Console.WriteLine($"長い日付: {dateTime:D}");
Console.WriteLine($"短い時刻: {dateTime:t}");
Console.WriteLine($"長い時刻: {dateTime:T}");
Console.WriteLine($"フル: {dateTime:F}");
Console.WriteLine($"ISO 8601: {dateTime:yyyy-MM-ddTHH:mm:ss}");
Console.WriteLine($"和暦: {dateTime.ToString("gg yy年M月d日", new CultureInfo("ja-JP"))}");
// TimeSpanフォーマット
var timeSpan = new TimeSpan(1, 2, 3, 4, 567);
Console.WriteLine($"\nTimeSpan: {timeSpan:d\\d\\ hh\\:mm\\:ss\\.fff}");
// 複雑なオブジェクトの表示
var product = new
{
Id = 12345,
Name = "スマートフォン",
Price = 89800m,
InStock = true,
Categories = new[] { "電子機器", "通信機器", "スマートフォン" },
Specifications = new Dictionary<string, object>
{
{ "OS", "Android 14" },
{ "RAM", "8GB" },
{ "Storage", "256GB" }
}
};
Console.WriteLine("\n=== 商品情報 ===");
Console.WriteLine($"商品ID: {product.Id}");
Console.WriteLine($"商品名: {product.Name}");
Console.WriteLine($"価格: {product.Price:C}");
Console.WriteLine($"在庫: {(product.InStock ? "あり" : "なし")}");
Console.WriteLine($"カテゴリ: {string.Join(" > ", product.Categories)}");
Console.WriteLine("仕様:");
foreach (var spec in product.Specifications)
{
Console.WriteLine($" {spec.Key}: {spec.Value}");
}
// パフォーマンス考慮のStringBuilder使用例
var sb = new StringBuilder();
sb.AppendLine("=== レポート ===");
for (int i = 1; i <= 5; i++)
{
sb.AppendLine($"項目 {i}: 値 {i * 10}");
}
Console.WriteLine(sb.ToString());
// エラーメッセージのフォーマット
string errorCode = "E001";
string errorMessage = "データベース接続エラー";
string details = "接続タイムアウトが発生しました";
Console.WriteLine($"\n❌ エラー [{errorCode}]: {errorMessage}");
Console.WriteLine($" 詳細: {details}");
Console.WriteLine($" 時刻: {DateTime.Now:yyyy/MM/dd HH:mm:ss}");
}
}
実用的なロギングパターン
using System;
using System.IO;
using System.Runtime.CompilerServices;
class Program
{
private static readonly string LogFilePath = "application.log";
static void Main()
{
// シンプルなログ機能の実装
LogInfo("アプリケーション開始");
try
{
ProcessData();
LogInfo("データ処理完了");
}
catch (Exception ex)
{
LogError("データ処理エラー", ex);
}
finally
{
LogInfo("アプリケーション終了");
}
}
static void ProcessData()
{
LogDebug("データ処理開始");
// データ処理のシミュレーション
for (int i = 1; i <= 3; i++)
{
LogInfo($"ステップ {i} 実行中");
System.Threading.Thread.Sleep(500); // 処理時間のシミュレーション
}
// 警告の例
LogWarning("一部のデータが古い可能性があります");
LogDebug("データ処理終了");
}
// ログレベル列挙型
enum LogLevel
{
Debug,
Info,
Warning,
Error
}
// 基本ログメソッド
static void Log(LogLevel level, string message, Exception exception = null,
[CallerMemberName] string memberName = "",
[CallerFilePath] string sourceFilePath = "",
[CallerLineNumber] int sourceLineNumber = 0)
{
var timestamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");
var fileName = Path.GetFileName(sourceFilePath);
var logMessage = $"[{timestamp}] [{level.ToString().ToUpper()}] {message}";
if (exception != null)
{
logMessage += $"\n Exception: {exception.Message}";
logMessage += $"\n StackTrace: {exception.StackTrace}";
}
// コンソール出力(色分け)
var originalColor = Console.ForegroundColor;
Console.ForegroundColor = GetLogColor(level);
Console.WriteLine(logMessage);
Console.ForegroundColor = originalColor;
// ファイル出力(オプション)
try
{
File.AppendAllText(LogFilePath, logMessage + Environment.NewLine);
}
catch
{
// ファイル書き込みエラーは無視
}
// デバッグ情報(デバッグモードのみ)
#if DEBUG
if (level >= LogLevel.Warning)
{
Console.WriteLine($" Source: {fileName}:{sourceLineNumber} in {memberName}()");
}
#endif
}
static ConsoleColor GetLogColor(LogLevel level)
{
return level switch
{
LogLevel.Debug => ConsoleColor.Gray,
LogLevel.Info => ConsoleColor.White,
LogLevel.Warning => ConsoleColor.Yellow,
LogLevel.Error => ConsoleColor.Red,
_ => ConsoleColor.White
};
}
// 各ログレベル用の便利メソッド
static void LogDebug(string message) => Log(LogLevel.Debug, message);
static void LogInfo(string message) => Log(LogLevel.Info, message);
static void LogWarning(string message) => Log(LogLevel.Warning, message);
static void LogError(string message, Exception ex = null) => Log(LogLevel.Error, message, ex);
// 構造化ログのシミュレーション
static void LogStructured(string eventName, object data)
{
var timestamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");
Console.WriteLine($"[{timestamp}] [EVENT] {eventName}");
if (data != null)
{
var properties = data.GetType().GetProperties();
foreach (var prop in properties)
{
var value = prop.GetValue(data);
Console.WriteLine($" {prop.Name}: {value}");
}
}
}
}