为什么out参数不能有默认值?

本文关键字:默认值 不能 out 参数 为什么 | 更新日期: 2023-09-27 18:05:57

当前,当尝试在方法中做一些带有out参数的事情时,我需要在方法体中分配out参数的值,例如

public static void TryDoSomething(int value, out bool itWorkerd)
{
    itWorkerd = true;
    if (someFavourableCondition)
    {
        // if I didn't assign itWorked variable before this point, 
        // I get an error: "Parameter itWorked must be assigned upon exit.
        return;
    }
    // try to do thing
    itWorkerd = // success of attempt to do thing
}

我希望能够设置itWorked参数的默认值,这样我就不必在方法体中任意设置该值。

public static void TryDoSomething(int value, out bool itWorkerd = true)
{
    if (someFavourableCondition)
    {
        // itWorked was already assigned with a default value
        // so no compile errors.
        return;
    }
    // try to do thing
    itWorkerd = // success of attempt to do thing
}

为什么不能为out参数分配默认值?

为什么out参数不能有默认值?

按值传递的参数有默认值。参数仍然传递给函数,但如果代码省略了参数,编译器将提供缺失的值。

你提出的特性很不一样。与其让调用者省略传递该值,不如让函数的实现者省略设置该值。这是一个完全不同的特征。为什么没有实施?以下是一些可能的原因:

  1. 没有人想到要实现这个功能。
  2. 设计师考虑了这个功能,并拒绝了它,因为它不够有用,不值得实现它。
  3. 设计师考虑了这个功能,并拒绝了它,因为它使用了与默认值参数相似的语法,但具有完全不同的含义。

我知道这并没有完全回答最初的问题,但我无法为评论做出贡献。我自己也有同样的问题,所以发现自己在这里。

由于c# 7现在允许out形参在调用范围内有效地作为变量声明,因此赋一个默认值将是有用的。

考虑下面的简单方法:

private void ResolveStatusName(string statusName, out string statusCode)
    {
        statusCode = "";
        if (statusName != "Any")
        {
            statusCode = statusName.Length > 1
                ? statusName.Substring(0, 1)
                : statusName;
        }
    }

像这样修改它感觉很直观:

 private void ResolveStatusName(string statusName, out string statusCode = "")
    {
        if (statusName != "Any")
        {
            statusCode = statusName.Length > 1
                ? statusName.Substring(0, 1)
                : statusName;
        }
    }

目的是不仅声明statusCode值,而且定义它的默认值,但编译器不允许

即使它允许您提供这样的默认值,它仍然要求您为所有返回值分配参数值。所以你的默认值将被覆盖。

默认参数值是在中传递给方法的参数的默认值。您必须指定一个变量来传递out参数,以便您可以获得返回值。

你的第一个例子,在某种程度上,有一个默认的,设置在方法的开始

方法参数上的out方法参数关键字导致方法引用传递给该方法的相同变量。当控制权传回调用方法时,对方法中参数所做的任何更改都将反映在该变量中。当您希望一个方法返回多个值时,声明out方法很有用。使用out参数的方法仍然可以返回值。一个方法可以有多个输出参数。要使用out形参,必须将实参显式地作为out实参传递给方法。out参数的值不会传递给out形参。作为输出参数传递的变量不需要初始化。但是,out形参必须在方法返回之前赋值。

编译器不允许你使用out形参作为默认形参,因为它违反了它的用例。如果你不把它传递给函数,你就不能在调用函数时使用它的值。

如果你可以调用下面的函数,如TryDoSomething(123),那么没有使用out参数,因为你将无法使用itWorked的值

public static void TryDoSomething(int value, out bool itWorkerd = true)
{
    if (someFavourableCondition)
    {
        // itWorked was already assigned with a default value
        // so no compile errors.
        return;
    }
    // try to do thing
    itWorkerd = // success of attempt to do thing
}

如果你有两次调用使用'out'或'ref'的方法,并且你想避免将方法分成两个,如果其中一个调用没有使用这些参数,一个优雅的解决方案可以避免编译器发出"该值未被使用"的警告;(或类似的东西),是使用像这样的东西:

method("hi", out _);

用'out'声明的方法参数不能由调用者为其赋值。因此,在调用期间也不能分配默认值。

同样,在使用'out'形参或从方法返回之前,必须始终在方法体中初始化该形参。这将覆盖任何默认值。

这就是'out'修饰符的全部意义。如果你想要一个不同的行为,检查'ref'和'in'修饰符。