【问题标题】:Why does C# handle command line args inconsistently?为什么 C# 处理命令行参数不一致?
【发布时间】:2011-05-25 10:05:35
【问题描述】:

在 C# 中,直接从 Main() 获取命令行参数会省略 exe 名称,这与 C 的传统相反。

通过 Environment.GetCommandLineArgs 获取相同的命令行参数包括它。

我是否因为这种明显的不一致而遗漏了一些很好的逻辑原因?

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine(string.Format("args.Length = {0}", args.Length));

        foreach(string arg in args)
        {
            Console.WriteLine(string.Format("args = {0}", arg));
        }

        Console.WriteLine("");

        string[] Eargs = Environment.GetCommandLineArgs();
        Console.WriteLine(string.Format("Eargs.Length = {0}", Eargs.Length));
        foreach (string arg in Eargs)
        {
            Console.WriteLine(string.Format("Eargs = {0}", arg));
        }

    }
}

输出:

C:\\ConsoleApplication1\ConsoleApplication1\bin\Debug>consoleapplication1 xx zz aa 
args.Length = 3 
args = xx
args = zz 
args = aa
Eargs.Length = 4 
Eargs = consoleapplication1 
Eargs = xx 
Eargs = zz 
Eargs = aa

【问题讨论】:

标签: c# visual-studio command-line


【解决方案1】:

因为它不是 C,因此不依赖于它的约定。需要 exe 名称几乎是一种极端情况。我需要这个的次数很少(与其他 args 相比)IMO 证明了省略它的决定。

这是规范中的额外要求(ECMA334v4,§10.1); (截取相关部分):

10。基本概念

10.1 应用启动

...

这个入口点方法总是被命名为Main,并且应该有一个 以下签名:

static void Main() {…} 
static void Main(string[] args) {…} 
static int Main() {…} 
static int Main(string[] args) {…} 

...

• 让args 成为参数的名称。如果args指定的数组长度大于 零,数组成员args[0]args[args.Length-1],包括在内,应指字符串, 称为应用程序参数,由宿主环境赋予实现定义的值 在应用程序启动之前。目的是向应用程序提供之前确定的信息 从托管环境中的其他地方启动应用程序。如果宿主环境不能 提供带有大写和小写字母的字符串,实现应确保 字符串以小写形式接收。 [注意:在支持命令行、应用程序、应用程序参数的系统上 对应于通常称为命令行参数的内容。 结束说明]

【讨论】:

  • + 他们给了你一个获得它的方法(真的有几个)
  • 我认为这个问题仍然有效。为什么要区分 args 数组和 Environment.GetCommandLineArgs() 结果。忘了C,为什么这两种方法有区别?
  • @BFree 是为了降低复杂性。当您通常处理命令行事件时,您不需要其他必须排除的废话。想想foreach(string in args)for(int i=1;i<args.length;i++){process(args[i]);}(即使 foreach-in 可能是一个更糟糕的策略,我希望你考虑这个概念)
  • @drachenstern:我同意可执行文件名称很少有用的想法,但只是为了进一步说明这个论点,为什么他们将可执行文件名称包含在Environment.GetCommandLineArgs()?他们不应该保持一致吗?如果是我,我会让它们保持不变,并且可能有一个单独的只读属性,如“Environment.ExecutableName”或其他......
  • @BFree ~ 这是 Eric Lippert 之类的问题;)
【解决方案2】:

[设计状态] -- http://msdn.microsoft.com/en-us/library/acy3edy3(v=VS.100).aspx

与 C 和 C++ 不同,程序的名称不被视为第一个命令行参数。

【讨论】:

  • 我的困难不在于它是否被视为命令行参数 - 我可以接受任何一种方式。我的困难是,在一种情况下它是,而在另一种情况下它不是。
  • 有趣的引用,直到一个名为 GetCommandLineArgs() 的函数将程序的名称视为第一个命令行参数
【解决方案3】:

对我来说,这两种方法返回不同结果的原因是Context

  • Environment 类用于操作当前环境和进程,Environment.GetCommandLineArgs(); 返回可执行文件名是有意义的,因为它是进程的一部分。

  • 至于 args 数组,对我来说排除可执行文件名是有意义的。我知道我正在调用可执行文件,并且在运行我的应用程序的上下文中,我想知道向它发送了哪些参数。

归根结底,拥有两种选择的方法是很强大的。

【讨论】:

  • +1 我在回答中途看到了这些帖子,这就是我要提到的,这完全是电话的观点(上下文)问题
  • 人们过去常常根据可执行文件的名称来改变执行路径,因为它包含在 arglist 中。如果文件被命名为move.exe,他们会默认移动文件,如果是copy.exe,则默认复制,等等。愚蠢的编译器技巧,但仍然这样做。
  • er,那些不是编译器技巧,而是运行时,但无论如何,我的观点仍然成立。
猜你喜欢
  • 2013-05-08
  • 2015-07-02
  • 1970-01-01
  • 2023-04-03
  • 2015-05-01
  • 1970-01-01
  • 2010-09-08
  • 1970-01-01
相关资源
最近更新 更多