Console.WriteLine

.NET標準のコンソール出力メソッド。設定不要で即座に利用可能な最もシンプルなロギング手段。開発・デバッグ段階での迅速な出力確認に適しているが、本番環境では機能が限定的。プロトタイピングに最適。

ロギングライブラリC#.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出力、分析ツール統合の限界
  • エンタープライズ要件に対する機能不足

参考ページ

書き方の例

基本的な文字列出力

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}");
            }
        }
    }
}