C#开发基础之借用dotnet CLI命令行参数的设计了解命令行构建用法

在这里插入图片描述

前言

在C#开发中,命令行参数是一种重要的机制,用于在程序启动时向应用程序传递配置或指令。无论是构建CLI工具还是配置化启动的桌面程序,掌握命令行参数的用法可以帮助我们设计更灵活的应用程序。
本文将详细介绍C#中命令行参数的基本用法、高级处理技巧以及常见的第三方库,并结合实际代码示例说明。

一、命令行参数的基础用法

1. 命令行参数的基本概念

在C#中,命令行参数通过Main方法的string[] args参数传递。
例如,如果从命令行运行以下命令:

dotnet run arg1 arg2 arg3

args将包含以下值:

args[0] = "arg1";
args[1] = "arg2";
args[2] = "arg3";

2. 示例代码

下面展示了如何在Main方法中处理命令行参数:

using System;

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("接收到的命令行参数:");
        for (int i = 0; i < args.Length; i++)
        {
            Console.WriteLine($"参数 {i + 1}: {args[i]}");
        }
    }
}

运行:

dotnet run Hello World

输出:

接收到的命令行参数:
参数 1: Hello
参数 2: World

二、高级命令行参数处理

1. 使用带有键值对的参数

如果需要处理类似--key=value的参数格式,可以进行简单的字符串解析:

using System;

class Program
{
    static void Main(string[] args)
    {
        foreach (var arg in args)
        {
            if (arg.Contains('='))
            {
                var parts = arg.Split('=', 2); // 按等号拆分
                var key = parts[0].TrimStart('-');
                var value = parts[1];
                Console.WriteLine($"Key: {key}, Value: {value}");
            }
            else
            {
                Console.WriteLine($"单一参数: {arg}");
            }
        }
    }
}

运行:

dotnet run --name=dotnet --version=9.0 standalone

输出:

Key: name, Value: dotnet
Key: version, Value: 9.0
单一参数: standalone

2. 解析带有标志的参数

标志参数如-h--help通常是布尔值,用于启用特定功能。示例代码如下:

using System;

class Program
{
    static void Main(string[] args)
    {
        bool showHelp = false;
        foreach (var arg in args)
        {
            if (arg == "-h2" || arg == "--help2")
            {
                showHelp = true;
            }
        }
        if (showHelp)
        {
            Console.WriteLine("Usage: dotnet run [options]");
            Console.WriteLine("Options:");
            Console.WriteLine("  -h2, --help2     Show this message and exit");
        }
        else
        {
            Console.WriteLine("程序运行中...");
        }
    }
}

为了和原命令行区别,我在这里指定键值为h2或者help2
运行:

dotnet run -h2

输出:

Usage: dotnet run [options]
Options:
  -h2, --help2     Show this message and exit

三、使用第三方库简化命令行参数处理

手动解析命令行参数可能会导致代码复杂且容易出错。为了解决这个问题,可以使用第三方库,如 CommandLineParser 或 System.CommandLine。

1. 使用 CommandLineParser

安装 NuGet 包

运行以下命令安装:

dotnet add package CommandLineParser
 <ItemGroup>
   <PackageReference Include="CommandLineParser" Version="2.9.1" />
 </ItemGroup>
示例代码
using CommandLine;
using System;

class Program
{
    public class Options
    {
        [Option('n', "name", Required = true, HelpText = "输入名称。")]
        public string Name { get; set; }

        [Option('v', "version", Required = false, HelpText = "显示版本信息。")]
        public bool Version { get; set; }
    }

    static void Main(string[] args)
    {
        Parser.Default.ParseArguments<Options>(args)
            .WithParsed<Options>(opts =>
            {
                if (opts.Version)
                {
                    Console.WriteLine("版本: 1.0.0");
                }
                else
                {
                    Console.WriteLine($"你好, {opts.Name}!");
                }
            })
            .WithNotParsed(errors =>
            {
                Console.WriteLine("参数解析失败,请检查输入。");
            });
    }
}

运行:

dotnet run --name=dotnet --version

输出:

版本: 1.0.0

2. 使用 System.CommandLine

dotnet sdk中也使用当前包,进行dotnet cli的命令行工具开发
在这里插入图片描述
内部定义关键词
在这里插入图片描述

安装 NuGet 包
dotnet add package System.CommandLine
  <ItemGroup>
    <PackageReference Include="System.CommandLine" Version="2.0.0-beta4.22272.1" />
  </ItemGroup>
示例代码
using System;
using System.CommandLine;
using System.CommandLine.Invocation;

class Program
{
    static void Main(string[] args)
    {
        // 创建根命令
        var rootCommand = new RootCommand("示例命令行工具");
        var nameOption = new Option<string>(
            "--name1",
            description: "输入名称"
        );
        var versionOption = new Option<bool>(
            "--version1",
            description: "显示版本信息"
        );
        rootCommand.AddOption(nameOption);
        rootCommand.AddOption(versionOption);
        rootCommand.SetHandler((string name, bool version) =>
        {
            if (version)
            {
                Console.WriteLine("版本: 1.0.0");
            }
            Console.WriteLine($"你好, {name}!");
        }, nameOption, versionOption);
        var t =  rootCommand.InvokeAsync(args);
        Console.WriteLine(t.Result);
    }
}

为了和默认参数键名区别,我在这里指定键值为–name1和–version1

运行:

dotnet run --name1=dotnet --version1

输出

版本: 1.0.0
你好, dotnet!
0

四、常见的命令行参数格式

命令行参数有不同的传递格式,常见的包括:

  • 短选项(Short Option):通常是单个字符(例如 -f),后面跟一个值。
  • 长选项(Long Option):由一个或多个字符组成,通常使用 – 前缀(例如 --file)。
  • 标志参数(Flag Option):仅表示开关的参数(例如 --enableFeature),不需要值。

五、最佳实践

  1. 为用户提供帮助信息:始终提供--help-h选项。
  2. 校验输入:处理非法参数并提示用户。
  3. 保持一致的参数风格:例如统一使用--key=value格式或短标志-k
  4. 利用第三方库:简化代码,提高可维护性。

六、总结

C#中命令行参数的用法既可以通过手动解析实现,也可以借助第三方库完成高效的参数处理。根据应用的复杂度选择合适的方式,能够帮助开发者构建灵活、可靠的CLI应用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/921227.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【单元测试】【Android】JUnit 4 和 JUnit 5 的差异记录

背景 Jetbrain IDE 支持生成 Test 类&#xff0c;其中选择JUnit5 和 JUnit&#xff0c;但是感觉这不是标准的单元测试&#xff0c;因为接口命名吧。 差异对比 两者生成的单测API名称同原API&#xff0c;没加test前缀的。使用差异主要表现在&#xff1a; setUp &#xff06; …

网页中调用系统的EXE文件,如打开QQ

遇到一个实际的问题&#xff0c;需要在网页中打开本地的某个工业软件。 通过点击exe文件就可以调用到程序。 比如双击qq的exe就可以启动qq的程序。 那么问题就变成了如何加载exe程序呢&#xff1f; 可以通过Java的 Process process Runtime.getRuntime().exec(command);通过…

FME教程:实现按属性字段合并图斑,同时合并属性字段值,对合并的属性值同步进行去重处理的案例思路方法

目录 一、实现效果 二、实现过程 1.读取数据 2.融合图斑 3.合并属性字段值&#xff0c;并去重 4.属性字段值排序、整理 5.输出成果 6.模板的使用 三、总结 今天介绍使用FME实现按属性合并图斑&#xff0c;同时合并属性字段值&#xff0c;并对合并的属性值同步进行去重…

ant-design-vue中table组件多列排序

antD中table组件多列排序 使用前注意实现效果图实现的功能点及相关代码1. 默认按某几个字段排序2. 点击排序按钮可同时对多个字段进行排序3. 点击重置按钮可恢复默认排序状态。 功能实现完整的关键代码 使用前注意 先要确认你使用的antD版本是否支持多列排序&#xff0c;我这里…

【LeetCode热题100】栈

这道题一共记录了关于栈的5道题目&#xff1a;删除字符串中所有相邻重复项、比较含退格的字符串、基本计算器II、字符串解码、验证栈序列。 class Solution { public:string removeDuplicates(string s) {string ret;for(auto c : s){if(ret.size() 0 || c ! ret.back()) ret …

IText创建加盖公章的pdf文件并生成压缩文件

第一、前言 此前已在文章&#xff1a;Java使用IText根据pdf模板创建pdf文件介绍了Itex的基本使用技巧&#xff0c;本篇以一个案例为基础&#xff0c;主要介绍IText根据pdf模板填充生成pdf文件&#xff0c;并生成压缩文件。 第二、案例 以下面pdf模板为例&#xff0c;生成一个p…

C语言——数组逐元素操作练习

定义一个能容纳10个元素的整形数组a&#xff0c;从键盘读取9个整数存放到前9个数组元素中。 一. 从键盘读取一个整数n和位置p(0<p<8)&#xff0c;插入n到数组a中&#xff0c;插入位置&#xff1a;下标p。要求插入点及后续的数组元素都要后移动。 代码如下&#xff1a; …

“iOS profile文件与私钥证书文件不匹配”总结打ipa包出现的问题

目录 文件和证书未加载或特殊字符问题 证书过期或Profile文件错误 确认开发者证书和私钥是否匹配 创建证书选择错误问题 申请苹果 AppId时勾选服务不全问题 ​总结 在上线ios平台的时候&#xff0c;在Hbuilder中打包遇见了问题&#xff0c;生成ipa文件时候&#xff0c;一…

网络安全之内网安全

下面给出了应对企业内网安全挑战的10种策略。这10种策略即是内网的防御策略&#xff0c;同时也是一个提高大型企业网络安全的策略。 1、注意内网安全与网络边界安全的不同 内网安全的威胁不同于网络边界的威胁。网络边界安全技术防范来自Internet上的攻击&#xff0c;主要是防…

项目总结模版

测试过程记录文档模版 我们经常测试经常需要做项目总结&#xff0c;所以小编这边就整理了一套项目总结模版&#xff0c;希望能够帮助到大家。 一、需求描述 对应指标&#xff1a;记录需求做的价值&#xff0c;用来评估后续项目上线后是否满足预期结果 1、需求文档 上传相关…

visual code:主题背景色的更换、常规设置

1、直接设置 进入界面->工具->主题->选择主题 2、常规设置 进入界面->工具->选项->环境->常规

低速接口项目之串口Uart开发(四)——UART串口实现FPGA内部AXILITE寄存器的读写控制

本节目录 一、设计背景 二、设计思路 三、逻辑设计框架 四、仿真验证 五、上板验证 六、往期文章链接本节内容 一、设计背景 通常&#xff0c;芯片手册或者IP都会提供一系列的用户寄存器以及相关的定义&#xff0c;用于软件开发人员进行控制底层硬件来调试&#xff0c;或封装…

python高阶技巧一

闭包 简单认识一下闭包 以下代码&#xff0c;内层inner函数不仅依赖于自身的参数b&#xff0c;还依赖于外层outer函数的参数a。inner就是一个闭包函数&#xff0c;既能访问外部变量&#xff0c;又保证外部变量不是全局的&#xff0c;不会被篡改掉&#xff0c;确保了外部变量的…

Redis最终篇分布式锁以及数据一致性

在前三篇我们几乎说完了Redis的所有的基础知识以及Redis怎么实现高可用性,那么在这一篇文章中的话我们主要就是说明如果我们使用Redis出现什么问题以及解决方案是什么,这个如果在未来的工作中也有可能会遇到,希望对看这篇博客的人有帮助,话不多说直接开干 一.Hotkey以及BigKey…

湘潭大学人工智能考试复习1(软件工程)

今年的试卷分值分布为&#xff1a; 选填40&#xff0c;两道计算题15x2 两道解答题15x2 复习重点&#xff1a; 1.人工智能学派派别 符号主义学派、连接主义学派、行为主义学派 各学派认知观&#xff1a; 符号主义&#xff08;逻辑主义、心理学派、计算机学派&#xff09;&am…

【蓝桥杯C/C++】深入解析I/O高效性能优化:std::ios::sync_with_stdio(false)

博客主页&#xff1a; [小ᶻZ࿆] 本文专栏: 蓝桥杯C/C 文章目录 &#x1f4af;前言&#x1f4af;C 语言与 C 语言的输入输出对比1.1 C 语言的输入输出1.2 C 语言的输入输出 &#x1f4af; std::ios::sync_with_stdio(false) 的作用与意义2.1 什么是 std::ios::sync_with_st…

GPT1.0 和 GPT2.0 的联系与区别

随着自然语言处理技术的飞速发展&#xff0c;OpenAI 提出的 GPT 系列模型成为了生成式预训练模型的代表。作为 GPT 系列的两代代表&#xff0c;GPT-1 和 GPT-2 虽然在架构上有着继承关系&#xff0c;但在设计理念和性能上有显著的改进。本文将从模型架构、参数规模、训练数据和…

嵌入式系统与OpenCV

目录 一、OpenCV 简介 二、嵌入式 OpenCV 的安装方法 1. Ubuntu 系统下的安装 2. 嵌入式 ARM 系统中的安装 3. Windows10 和树莓派系统下的安装 三、嵌入式 OpenCV 的性能优化 1. 介绍嵌入式平台上对 OpenCV 进行优化的必要性。 2. 利用嵌入式开发工具&#xff0c;如优…

戴尔 AI Factory 上的 Agentic RAG 搭载 NVIDIA 和 Elasticsearch 向量数据库

作者&#xff1a;来自 Elastic Hemant Malik, Dell Team 我们很高兴与戴尔合作撰写白皮书《戴尔 AI Factory with NVIDIA 上的 Agentic RAG》。白皮书是一份供开发人员参考的设计文档&#xff0c;概述了实施 Agentic 检索增强生成 (retrieval augmented generation - RAG) 应用…

特征交叉-MaskNet文章总结代码实现

MaskNet 这个模型是微博21年提出的&#xff0c;23年twitter(X)开源的推荐系统排序模块使用的backbone结构。 核心思想是认为DNN为主的特征交叉是addictive&#xff0c;交叉效率不高&#xff1b;所以设计了一种multiplicatvie的特征交叉 如何设计muliplicative特征交叉呢&#x…