dotnet new console 一行生成默认顶层语句风格的控制台项目,支持 --use-program-main 回退传统结构;参数解析推荐 System.CommandLine,中文输出需显式设 Console.OutputEncoding = UTF8。

用 dotnet new console 创建最简控制台项目
新建控制台应用不用手动建文件夹、改 csproj 或配 SDK 版本,dotnet new console 一行命令就能生成可直接运行的骨架。它默认使用最新稳定版 .NET SDK(如 .NET 8),生成的 Program.cs 是顶层语句风格,没有显式 Main 方法——这对入门友好,但容易让人忽略入口逻辑其实还在那儿。
- 如果需要兼容旧项目结构(比如要重载
Main方法或处理返回码),加--use-program-main参数:dotnet new console --use-program-main - 别手动删
obj/或bin/目录来“清理”,用dotnet clean更安全;否则可能触发 MSBuild 缓存异常 - 生成后直接
dotnet run就能输出 “Hello, World!”,不需要先dotnet build——但发布到其他机器时必须用dotnet publish
读取命令行参数:别只用 args 数组硬写判断
string[] args 是 Main 方法的默认参数,但它只是原始字符串切片,没做解析。直接写 if (args.Length > 1 && args[0] == "-f") 这类逻辑,遇到空格、引号、长选项(如 --output-path)就崩。
- 简单场景用
System.Environment.GetCommandLineArgs(),它比args多包含程序名,索引从 0 开始,注意别越界 - 中等复杂度推荐
Microsoft.Extensions.CommandLineUtils(已归档)或更现代的System.CommandLine包(NuGet 安装System.CommandLinev2.0+) - 避免把参数解析逻辑塞进
Main:提取成独立方法或类,方便单元测试——比如验证-v是否被识别为布尔开关,而不是靠args.Contains("-v")
Console.ReadLine() 和 Console.ReadKey() 的行为差异
两者都读用户输入,但触发时机和返回值完全不同:ReadLine() 等回车才返回整行字符串(含换行符前内容),ReadKey() 按下任意键立刻返回,且默认不显示字符(适合密码输入或快捷键)。
-
ReadKey(true)表示“不显示按键”,ReadKey(false)才会回显——这个布尔参数极易被忽略,导致用户按了键却看不见反馈 - 在 Windows 上,
ReadLine()遇到 Ctrl+Z 会返回null(表示 EOF),Linux/macOS 下是 Ctrl+D;别用== ""判空,要用string.IsNullOrEmpty() - 如果程序需要非阻塞读取(比如边运行边监听输入),
Console.KeyAvailable必须配合ReadKey()使用,单独轮询KeyAvailable不会消耗输入缓冲区
输出中文乱码?检查 Console.OutputEncoding 和终端编码
Windows 默认控制台是 GBK(如 chcp 936),而 C# 默认用 UTF-8 输出,一来一回就变问号或方块。这不是代码写错了,是编码握手失败。
- 最稳方案:启动时强制设为 UTF-8:
Console.OutputEncoding = System.Text.Encoding.UTF8;,并确保终端支持(Windows Terminal / VS Code 终端默认 OK,传统 cmd 需先执行chcp 65001) - 别依赖
Console.WriteLine("你好")能不能显示——它可能“看起来”正常,但重定向到文件时(dotnet run > out.txt)仍会丢字节,因为重定向走的是不同流路径 - .NET 6+ 在 Windows 上启用了“UTF-8 默认模式”(通过
DOTNET_SYSTEM_GLOBALIZATION_PREDEFINED_CULTURES_ONLY=false环境变量),但仅影响新进程,老系统或容器里仍需显式设置
命令行参数解析和编码问题,往往在本地调试时完全正常,一放到 CI 环境或另一台机器就出错。不是代码有问题,而是你没意识到 Console 的行为高度依赖宿主环境和 .NET 运行时版本。


















