我怎么知道使用默认值?

Joh*_*Woo 24 .net c#

考虑这样的方法:

public void WorkAt(string location = @"home")
{
    //...
}
Run Code Online (Sandbox Code Playgroud)

可以通过显式传递值来调用它,例如:

WorkAt(@"company");
WorkAt(@"home");
Run Code Online (Sandbox Code Playgroud)

或者只使用默认值,例如:

WorkAt();
Run Code Online (Sandbox Code Playgroud)

有没有办法知道是否使用默认值?

例如,我想这样编码:

public void WorkAt(string location = @"home")
{
     if ( /* the default value is used unexplicitly */)
     {
         // Do something
     }
     else
     {
         // Do another thing
     }
}
Run Code Online (Sandbox Code Playgroud)

请注意WorkAt("home")WorkAt()此相关的不同之处.

lc.*_*lc. 66

没有,也不应该有任何理由这样做.默认值就是这样做 - 当没有指定时提供默认值.

如果你需要根据传递的内容执行不同的功能,我建议重载方法.例如:

public void WorkAt()
{
    //do something
}

public void WorkAt(string location)
{
    //do other thing
}
Run Code Online (Sandbox Code Playgroud)

或者,如果存在共享逻辑,则可以使用其他参数:

public void WorkAt(string location = "home", bool doOtherThingInstead = false)
{
    if (!doOtherThingInstead)
    {
        //do something
    }
    else
    {
        //do other thing
    }

    //do some shared logic for location, regardless of doOtherThingInstead
}
Run Code Online (Sandbox Code Playgroud)

作为旁注,或许问题中的例子是人为的,但WorkAt()没有指定参数就没有词汇意义.人们会想到这个词后的值.也许您可能想要重命名第二种方法WorkAtDefaultLocation().

  • @SriramSakthivel在这种情况下,我将不得不递归地将他们引用到这个答案.嗯,我想我们刚刚在Stack Overflow上出现了堆栈溢出.:-P (22认同)
  • 现在OP会问如何找到明确传递的`doOtherThingInstead = false`?:P (13认同)
  • @ M.kazem Akhgary这可能是一种有趣的练习,但仍然没有理由这样做.OP表示WorkAt("home")与WorkAt()不同.如果它们不同,那就让它们与众不同.尝试使它们变得相同没什么意义. (5认同)

Moh*_*ara 10

您的答案可能类似于以下代码.

public void CommonOperations(/*Some parameteres as needed.*/)
{
    // Shared operations between two methods.
}
public void WorkAt()
{
    string location = "home";
    CommonOperations(/*Some parameteres as needed.*/);
    //do something
}

public void WorkAt(string location)
{
    CommonOperations(/*Some parameteres as needed.*/);
    //do the other thing
}
Run Code Online (Sandbox Code Playgroud)

我希望它会有所帮助.


M.k*_*ary 9

你可以用它ReferenceEquals来达到这个目的.

但是,您发送的字符串不应该是编译时常量,否则string "home"具有与默认值相同的引用,"home"并将返回true.为什么?

要创建具有不同引用的字符串,您必须从该字符串进行深层复制.

    static void Main()
    {
        WorkAt(); // Prints true
        WorkAt("home"); // Prints true because the string is a compile-time constant

        // DeepClone before passing parameter to WorkAt.
        WorkAt(DeepClone("home"));// Prints false for any string.
    }

    static void WorkAt(string location = @"home")
    {
        if (ReferenceEquals(location, @"home")) // Only true when using default parameter
        {
            Console.WriteLine(true);
        }
        else
        {
            Console.WriteLine(false);
        }
    }

    static string DeepClone(string str) // Create a deep copy
    {
         return new string(str.ToCharArray());
    }
Run Code Online (Sandbox Code Playgroud)

请注意,这是了解是否使用默认值的唯一方法.因为默认值始终是编译时常量,但发送给方法的参数不是.

BTW为@lc.解释说实际上没有理由这样做,因为你可以使用方法重载.


小智 7

使用sentinel值而不是默认值

public void WorkAt(location="default_sentinel_value") {
    if (location == "default_sentinel_value") {
        location = "home";
        ...
    }
    else
    {
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 如果`null`不是函数的有效值,则可以使用null作为标记值. (3认同)
  • @Kevin:只要运行时没有查看字符串就可以实现字符串.如果确实如此,那么你的哨兵可能不会像你想象的那样私密,但是M.kazem的回答提出了一种防止实习的方法. (3认同)