C# 4.0 - 如何处理可选字符串参数

发布于 2024-09-17 00:53:45 字数 680 浏览 12 评论 0原文

此代码无效:

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 编译为 -时间常数?

This code is not valid:

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

But this code is:

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

Why? Because string.Empty is a readonly field, not a constant, and defaults for optional parameters must be a compile-time constant.

So, onto my question... (well, concern)

This is what i've had to do:

private const string emptyString = "";

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

How do you guys handle optional string parameters?

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

一向肩并 2024-09-24 00:53:46

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

const int Zero = 0;

void SomeMethod(int optional = Zero) { }

你觉得这很愚蠢吗?

Ummm... what's wrong with string optionalParm = "" again? Why is that bad? Do you really think you need a symbolic constant for an empty string in this case? How about this then?

const int Zero = 0;

void SomeMethod(int optional = Zero) { }

Does that seem at all silly to you?

半步萧音过轻尘 2024-09-24 00:53:46

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

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

if you don't like "" value you can use default(string).
I played with it and it is allowed.

private static void foo(string param = default(string)) {
    if (!string.IsNullOrEmpty(param)) // or param != default(string)
        Console.WriteLine(param);
}
桜花祭 2024-09-24 00:53:46

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

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

Code Analysis warning 1026 says not to use optional parameters. It's better style to use overload methods, like this:

private void Foo()
{
   Foo(string.Empty);
}
private void Foo(string optionalString)
{
   // do foo.
   if (!string.IsNullOrEmpty(optionalString))
      // etc
}
对你再特殊 2024-09-24 00:53:46

处理它们的最好方法是:

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

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

The best way to handle them is with:

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

So you can't use String.Empty. Everyone recognizes "", but if I found optionalString = nullString I wouldn't be sure what to think. If nothing else, name the thing emptyString--it's not null!

笑红尘 2024-09-24 00:53:46

我正在回答这个问题。

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

下面是通过 Reflector 对 mscorlib.dll 中的 String.cs 进行反汇编的代码,

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

I'm answering this question.

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

Here is the disassemble code via Reflector of String.cs in mscorlib.dll

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

So in windows platform, string.Empty is exactly "". But do you know, Martian have a different definition for Empty and WhitespaceChars in their OS.

心碎无痕… 2024-09-24 00:53:46

如果您愿意玩输,并将 null、"" 和空白字符视为相同,那么您可以默认为 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;
}

If you are willing to play lose and treat null, "", and whitespace characters to be the same, then you can default to null. This becomes very handy when user name and password are optional fields due to a possibility of trusted connection to a db. You could change this logic to reset strings to null and thus modify the assert and the if. The important part is having a consistent convention.

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;
}
有深☉意 2024-09-24 00:53:46
   private void Foo(string optionalString = emptyString)
    {
        if (string.IsNullOrEmpty(optionalString )) 
        { 
            return; 
        }
    }
   private void Foo(string optionalString = emptyString)
    {
        if (string.IsNullOrEmpty(optionalString )) 
        { 
            return; 
        }
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文