You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修改System.Console.WriteLine方法实现控制台与日志双输出?

解决方案:同时输出控制台与日志的简便实现

针对你遇到的Console静态类无法继承、重载过多的问题,最优解是利用.NET的Console.SetOut方法重定向输出流,无需手动实现18个重载,就能让所有Console.WriteLine调用自动同时写入日志和控制台。

方法一:自定义输出流(推荐)

通过继承TextWriter实现一个同时处理日志和原生控制台输出的自定义流,然后替换Console的默认输出流即可。

步骤1:实现自定义Writer类

using System.IO;
using System.Text;

public class ConsoleAndLogWriter : TextWriter
{
    private readonly TextWriter _originalConsoleOut;
    private readonly string _logFileName;

    public ConsoleAndLogWriter(string logFileName)
    {
        _originalConsoleOut = Console.Out;
        _logFileName = logFileName;
    }

    // 必须重写Encoding属性
    public override Encoding Encoding => _originalConsoleOut.Encoding;

    // 处理所有文本输出(覆盖基础写入逻辑,自动适配所有Write/WriteLine重载)
    public override void Write(char[] buffer, int index, int count)
    {
        string outputText = new string(buffer, index, count);
        // 过滤空行(可选,根据需求调整)
        if (!string.IsNullOrWhiteSpace(outputText.TrimEnd('\r', '\n')))
        {
            Logger.WriteLog(outputText.TrimEnd('\r', '\n'), _logFileName);
        }
        // 输出到原生控制台
        _originalConsoleOut.Write(buffer, index, count);
    }

    // 可选:单独处理无参WriteLine,避免空行日志
    public override void WriteLine()
    {
        _originalConsoleOut.WriteLine();
    }
}

步骤2:程序启动时替换输出流

在程序入口(比如Main方法开头)执行以下代码,之后所有Console.WriteLine都会自动同步日志:

// 初始化自定义输出流,指定日志文件名
Console.SetOut(new ConsoleAndLogWriter("MyApplicationLog"));

// 测试调用
Console.WriteLine("Hello World!");
Console.WriteLine(123);
Console.WriteLine(true);

方法二:反射包装类(备选)

如果不想重定向输出流,可以用反射动态调用Console的重载方法,同时触发日志写入。这种方式需要替换原有代码中的Console为自定义静态类,但无需手动实现所有重载:

using System.Reflection;

public static class LoggingConsole
{
    private static readonly Type _consoleType = typeof(Console);
    private const string DefaultLogFileName = "MyAppLog";

    public static void WriteLine(params object[] args)
    {
        // 生成日志文本
        string logText = args.Length == 0 ? string.Empty : string.Join(" ", args);
        Logger.WriteLog(logText, DefaultLogFileName);

        // 反射调用对应重载的Console.WriteLine
        MethodInfo method;
        if (args.Length == 0)
        {
            method = _consoleType.GetMethod("WriteLine", Type.EmptyTypes);
        }
        else
        {
            Type[] argTypes = args.Select(a => a.GetType()).ToArray();
            method = _consoleType.GetMethod("WriteLine", argTypes);
        }
        method?.Invoke(null, args);
    }
}

使用示例

LoggingConsole.WriteLine("Hello World!");
LoggingConsole.WriteLine("Number:", 123);

对现有Logger的小优化

你的Logger.WriteLog方法中,Path.GetTempPath()返回的系统临时目录必然存在,因此可以去掉Directory.Exists的判断,简化代码:

// 原代码中这部分可以删除
// if (!Directory.Exists(destPath))
//     Directory.CreateDirectory(destPath);

内容的提问来源于stack exchange,提问作者user2838376

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 11:40:52