19

此代码无效:

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成为编译时常量?

4

6 回答 6

15

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

const int Zero = 0;

void SomeMethod(int optional = Zero) { }

你觉得这很愚蠢吗?

于 2010-08-31T05:47:33.927 回答
6

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

private static void foo(string param = default(string)) {
    if (!string.IsNullOrEmpty(param)) // or param != default(string)
        Console.WriteLine(param);
}
于 2010-09-23T07:34:01.730 回答
4

代码分析警告 1026表示不要使用可选参数。使用重载方法更好,如下所示:

private void Foo()
{
   Foo(string.Empty);
}
private void Foo(string optionalString)
{
   // do foo.
   if (!string.IsNullOrEmpty(optionalString))
      // etc
}
于 2016-09-29T20:36:04.607 回答
2

处理它们的最佳方法是:

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

所以你不能使用 String.Empty。每个人都承认“”,但如果我发现optionalString = nullString我不知道该怎么想。 如果没有别的,命名事物emptyString——它不为空!

于 2010-08-31T05:48:06.620 回答
1

我正在回答这个问题。

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 有不同的定义。

于 2010-08-31T06:07:10.850 回答
0

如果你愿意玩输,并且把空、“”和空格字符视为相同,那么你可以默认为null. 当用户名和密码是可选字段时,这变得非常方便,因为有可能与数据库建立受信任的连接。您可以更改此逻辑以将字符串重置为null,从而修改 assert 和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;
}
于 2011-04-05T16:08:19.223 回答