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

C#4.0-如何处理可选字符串参数,c#,.net,string,c#-4.0,optional-parameters,C#,.net,String,C# 4.0,Optional Parameters,此代码无效: private void Foo(string optionalString = string.Empty) { // do foo. } 但这个代码是: private void Foo(string optionalString = "") { // do foo. } 为什么??因为string.Empty是一个只读字段,不是常量,可选参数的默认值必须是编译时常量 所以,关于我的问题。。。(嗯,担心) 这就是我必须做的: private const strin

此代码无效:

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
}
你们怎么处理可选的字符串参数


为什么它们不能使编译时成为常量?

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

const int Zero = 0;

void SomeMethod(int optional = Zero) { }

你觉得这很傻吗?

处理这些问题的最佳方法是:

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

所以不能使用String.Empty。每个人都认识“”,但如果我发现
optionalString=nullString
我就不知道该怎么想了如果没有其他内容,请将该内容命名为
emptyString
——它不是空的
我在回答这个问题

为什么不能生成字符串。请清空编译时常量?

下面是通过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正好是“”。但是你知道吗,火星人在他们的操作系统中对空字符和空格字符有不同的定义。

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

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

如果您愿意玩lose and treat 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;
}
private void RunSql(字符串serverName、字符串databaseName、字符串userName=null、字符串password=null)
{
用户名=条带(用户名);
密码=条带(密码);
//'MsTest'assert-在'Debug'和'Release'模式下工作。
断言你是平等的(
userName==String.Empty,
密码==字符串。空,
“用户名和密码应为空或非空!”;
Assert.IsFalse(String.IsNullOrWhiteSpace(serverName));
Assert.IsFalse(String.IsNullOrWhiteSpace(databaseName));
var cmdBuilder=新的StringBuilder();
AppendFormat(“sqlcmd-E-S{0}-d{1}”、服务器名、数据库名);
如果(userName.Length>0)
{
AppendFormat(“-U{0}-P{1}”,用户名,密码);
}
//完成命令字符串。
//运行可执行文件。
}
//想不出好名字。清空?使空?
专用字符串条(字符串源)
{
if(String.IsNullOrWhiteSpace(源))
{
返回字符串。空;
}
返回源;
}
说不要使用可选参数。最好使用重载方法,如下所示:

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

为什么不坚持使用“”?这就是我所做的,但那也是因为我不明白使用String.Empty的好处。必须是一个unicode的东西,但我从来没有担心过(至少现在还没有…哎呀),我很困惑为什么你认为你需要这样做。我认为<代码> nulList< /COD>一个令人困惑的名字,因为乍一看,我倾向于认为它是“代码> NUL/<代码>,而不是<代码>”“<代码>”。至于最后一个问题,请参见[为什么String.Empty不是常量?]()@戴夫,这里没有Unicode<代码>“可以;另请参见[在C#中,我应该使用string.Empty还是string.Empty或“”?]()@prateksaluja20-标题/标签提到了什么?@STW-为什么删除我的编辑?它没有添加到问题中-答案是:我没有攻击你,他们可能很直率,但你最初的问题并不完全中立。同意,我的命名很糟糕。我已经习惯于在大多数字符串操作中使用string.empty,以至于当我开始使用可选参数时,我不喜欢必须返回到“”。我想我会坚持下去的。我同意了,我说得不好。我已经习惯于在大多数字符串操作中使用string.empty,以至于当我开始使用可选参数时,我不喜欢必须返回到“”。猜猜我会坚持“.滑稽模式:如果你想让人们把你的代码读成‘零’而不是‘零’,那也许是好的。为什么这样粗鲁的回答?OP有一个合法的问题。默认(字符串)值为null,而不是空字符串。@allonhadaya,指定一个非空的默认值并不能阻止任何人显式传递
null
:-p.@binki,我不确定我是否理解你的观点。你什么意思?@allonhadaya,我忘了。也许我是想说默认值
null
比指定参数默认值
更有意义。在某些情况下,您确实希望区分空字符串和
null
,并且具有
null
的默认值意味着您的方法可以很好地处理显式指定的
null
值。虽然这与OP选择使用
而不是
null
…@binki有更多关系,但Aha-当默认值的选择是预期域的成员时,函数会变得混乱;然后它就不能再被用作可靠的信号
null
往往是比
更好的信号,因为它是
字符串
类型中暗示“无值”的唯一成员。