如何知道使用的是默认值?

本文关键字:默认值 何知道 | 更新日期: 2023-09-27 18:09:41

考虑这样一个方法:

public void WorkAt(string location = @"home")
{
    //...
}

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

WorkAt(@"company");
WorkAt(@"home");

或者直接使用默认值,比如:

WorkAt();

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

例如,我想这样编码:

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

注意WorkAt("home")WorkAt()在上下文中是不同的

如何知道使用的是默认值?

没有,也不应该有任何理由这样做。默认值的作用就是在没有指定时提供一个默认值。

如果您需要根据传递的内容执行不同的函数,我建议重载该方法。例如:

public void WorkAt()
{
    //do something
}
public void WorkAt(string location)
{
    //do other thing
}

或者,如果存在共享逻辑,您可以使用额外的参数:

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
}

作为旁注,也许问题中的例子是人为的,但是没有指定参数的WorkAt() 在词汇上没有意义。可以期望在处的字后面有一个值。也许您需要将第二个方法重命名为WorkAtDefaultLocation()

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

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
}

您可以使用ReferenceEquals

然而,你发送的字符串不应该是编译时常数,否则字符串"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());
    }

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

顺便说一句,@lc。因为可以使用方法重载,所以实际上没有必要这样做。

使用哨兵值代替默认值

public void WorkAt(location="default_sentinel_value") {
    if (location == "default_sentinel_value") {
        location = "home";
        ...
    }
    else
    {
        ...
    }
}

如果你使用面向对象,你可以创建一些GetSet属性。

private string pvt_default;
private string pvt_location;
public string location
{
    get
    {
        return this.pvt_location;
    }
    set
    {
        if (pvt_default == location)
        {
            // do somthing
        }
        this.pvt_location = location;
    }
}

将默认值改为null并改为@"home"

作为程序员,默认值是一个已知值,因此您可以像以下任何方法一样编写代码:

方法1:

public void WorkAt(string location = @"home")
{
    if (location == @"home")
    {
        // Do something
    }
    else
    {
        // Do another thing
    }
}

方法2:利用函数Over loading

//function(A) with default value
public static void samplemethod()
    {
       string defaultValue="home";
       //Do something
    }
//function (B) without default value
public static void samplemethod(string x)
    {
         //Do something
    }

那么samplemethod("someValue");将调用function(B), samplemethod();将调用function(A)