【问题标题】:C# 4.0 - How to Handle Optional String ParametersC# 4.0 - 如何处理可选字符串参数
【发布时间】:2011-04-06 02:22:23
【问题描述】:

此代码无效:

private void Foo(string optionalString = string.Empty)
{
   // do foo.
}

但是这段代码是:

private void Foo(string optionalString = "")
{
   // do foo.
}

为什么?因为 string.Empty 是只读字段,不是常量,可选参数的默认值必须是编译时常量。

那么,关于我的问题……(嗯,关心)

这是我必须做的:

private const string emptyString = "";

private void Foo(string optionalString = emptyString)
{
   // do foo.
   if (!string.IsNullOrEmpty(optionalString))
      // etc
}

你们如何处理可选的字符串参数?

为什么他们不能将String.Empty 设为编译时常量?

【问题讨论】:

  • 为什么不坚持使用“”?这就是我所做的一切,但这也是因为我不了解使用 String.Empty 的优势。必须是 unicode 的东西,但我不必担心(至少现在还没有……哎呀)
  • 我很困惑为什么你认为你需要这样做。我认为nullString 是一个令人困惑的名字,因为乍一看我倾向于认为它是null,而不是""。至于您的最后一个问题,请参阅 [ 为什么 String.Empty 不是常量? ](stackoverflow.com/questions/507923/…)。 @Dave,这里没有 Unicode 的东西。 "" 很好;另请参阅 [ 在 C# 中,我应该使用 string.Empty 还是 String.Empty 还是“”? ](stackoverflow.com/questions/263191/…)。
  • @prateeksaluja20 - 标题/标签提到了什么???
  • @STW - 你为什么要删除我的编辑??
  • 它没有添加到问题中 - 答案并没有攻击你,他们可能直言不讳,但你最初的问题并不完全中立。

标签: c# .net string c#-4.0 optional-parameters


【解决方案1】:

Code Analysis warning 1026 表示不使用可选参数。使用重载方法更好,如下所示:

private void Foo()
{
   Foo(string.Empty);
}
private void Foo(string optionalString)
{
   // do foo.
   if (!string.IsNullOrEmpty(optionalString))
      // etc
}

【讨论】:

    【解决方案2】:

    如果你愿意玩输并且把空字符、""、空格字符视为相同,那么你可以默认为null。当用户名和密码是可选字段时,这变得非常方便,因为有可能与数据库建立受信任的连接。您可以更改此逻辑以将字符串重置为null,从而修改断言和if。重要的是要有一致的约定。

    private void RunSql(string serverName, string databaseName, string userName = null, string password = null)
    {
        userName = Strip(userName);
        password = Strip(password);
    
        // The `MsTest` assert - works in both `Debug` and `Release` modes.
        Assert.AreEqual<bool>(
            userName == String.Empty,
            password == String.Empty,
            "User name and password should be either both empty or both non-empty!");
       Assert.IsFalse(String.IsNullOrWhiteSpace(serverName));
       Assert.IsFalse(String.IsNullOrWhiteSpace(databaseName));
    
       var cmdBuilder = new StringBuilder();
       cmdBuilder.AppendFormat("sqlcmd -E -S {0} -d {1} ", serverName, databaseName);
       if (userName.Length > 0)
       {
           cmdBuilder.AppendFormat("-U {0} -P {1} ", userName, password);
       }
    
       // Complete the command string.
       // Run the executable.
    }
    
    // Cannot think of a good name. Emptify? MakeNullIfEmpty?
    private string Strip(string source)
    {
        if (String.IsNullOrWhiteSpace(source))
        {
            return String.Empty;
        }
    
        return source;
    }
    

    【讨论】:

      【解决方案3】:

      如果您不喜欢 "" 值,您可以使用默认值(字符串)。
      我玩过它,它是允许的。

      private static void foo(string param = default(string)) {
          if (!string.IsNullOrEmpty(param)) // or param != default(string)
              Console.WriteLine(param);
      }
      

      【讨论】:

      • 默认(字符串)值为空,不是空字符串。
      • @allonhadaya,指定非null 默认值不会阻止任何人明确传递null :-p。
      • @binki,我不确定我是否理解您的观点。什么意思?
      • @allonhadaya,我忘了。也许我想说null 的默认值比指定"" 的参数默认值更有意义。在某些情况下,您确实希望区分空字符串和null,并且默认值null 意味着您的方法可以很好地处理明确指定的null 值。尽管这与 OP 选择使用 "" 而不是 null 有更多关系……
      • @ binki,aha - 函数在选择默认值的选择是预期域的成员时;然后它就不能再用作可靠的信号。 null 往往是比 "" 更好的信号,因为它是 string 类型中唯一暗示“没有价值”的成员。
      【解决方案4】:

      嗯... string optionalParm = "" 又怎么了?为什么这么糟糕?你真的认为在这种情况下你需要一个空字符串的符号常量吗?那这个怎么样?

      const int Zero = 0;
      
      void SomeMethod(int optional = Zero) { }
      

      你觉得这很傻吗?

      【讨论】:

      • 同意,我的名字很糟糕。我只是习惯于在大多数字符串操作中使用 string.empty,以至于当我开始使用可选参数时,我不喜欢我不得不回到“”的事实。猜猜我会坚持使用“”。
      • Facetious 模式:如果您希望人们将您的代码读为“零”而不是“无”,那么也许可以
      • 为什么会有如此粗鲁的回应? OP 有一个合理的问题。
      【解决方案5】:

      我正在回答这个问题。

      Why can they not make String.Empty a compile-time constant?

      这是mscorlib.dll中String.cs的Reflector反汇编代码

      public static readonly Empty;
      static String()
      {
          Empty = "";
          WhitespaceChars = new char[] { 
              '\t', '\n', '\v', '\f', '\r', ' ', '\x0085', '\x00a0', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 
              ' ', ' ', ' ', ' ', '​', '\u2028', '\u2029', ' ', ''
           };
      }
      

      所以在windows平台上,string.Empty就是""。但是你知道吗,Martian 在他们的操作系统中对 Empty 和 WhitespaceChars 有不同的定义。

      【讨论】:

        【解决方案6】:

        处理它们的最佳方法是:

        private void Foo(string optionalString = "")
        {
           // do foo.
        }
        

        所以你不能使用 String.Empty。每个人都认识“”,但如果我找到optionalString = nullString,我不知道该怎么想。 如果不出意外,请将其命名为 emptyString——它不为空!

        【讨论】:

        • 同意,我的名字很糟糕。我只是习惯于在大多数字符串操作中使用 string.empty,以至于当我开始使用可选参数时,我不喜欢我不得不回到“”的事实。猜猜我会坚持使用“”。
        猜你喜欢
        • 2013-04-10
        • 2010-11-06
        • 1970-01-01
        • 2012-07-01
        • 2011-03-25
        • 2012-10-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多