C#可选输出参数

时间:2014-05-21 21:18:11

标签: c# null out

有没有办法让方法的out参数可选?我有一个方法,需要几个参数在大多数时间返回null,但有时它们会有一个值。我试图找出是否有更好的方法来实现这一点,而不是先将值设置为null,或者在if / else之后将它们设置为null。这可能是唯一的方法,但是如果有可选的输出参数或类似的东西会很好。这是代码:

    private static void GetInitInfo(string initLine, string ncPointType, out double? relinquishDefault, out bool? ignoreRelinquishDefault, out bool? closedForStart, out bool? adjustDisabled)
    {
        relinquishDefault = null;
        ignoreRelinquishDefault = null;
        closedForStart = null;
        adjustDisabled = null;

        switch (ncPointType)
        {
            case "MSD":
                adjustDisabled = LastToken<bool?>(initLine);
                break;
            case "BO":
                relinquishDefault = SecondToken<double>(initLine);
                closedForStart = ThirdToken<bool?>(initLine);
                ignoreRelinquishDefault = !ForthToken<bool?>(initLine);//ignoreRelDef would be reverse of use initial value
                break;
            case "MSO":
                closedForStart = SecondToken<bool?>(initLine);
                relinquishDefault = ThirdToken<double>(initLine);
                ignoreRelinquishDefault = !ForthToken<bool?>(initLine);//ignoreRelDef would be reverse of use initial value
                break;
            case "AD":
                relinquishDefault = ThirdToken<double>(initLine);
                ignoreRelinquishDefault = false;
                break;
            case "BD":
                relinquishDefault = SecondToken<double>(initLine);
                adjustDisabled = LastToken<bool?>(initLine);
                ignoreRelinquishDefault = false;
                break;
            case "AOS":
                relinquishDefault = FirstToken<double>(initLine);
                ignoreRelinquishDefault = !ThirdToken<bool?>(initLine);//ignoreRelDef would be reverse of use initial value
                break;
        }
    }

4 个答案:

答案 0 :(得分:2)

根据C#4.0规范:第21.1节,不允许这样做。

解决方法是使用另一个没有out或ref参数的方法重载。

答案 1 :(得分:1)

使用带有没有参数的签名的重载:

private static void GetInitInfo(string initLine, string ncPointType)
{
  double? relinquishDefault;
  bool? ignoreRelinquishDefault;
  bool? closedForStart;
  bool? adjustDisabled;

  GetInitInfo( initLine, ncPointType, out relinquishDefault, out ignoreRelinquishDefault, 
    out closedForStart, out adjustDisabled);
}

答案 2 :(得分:1)

我相信这个问题要求不得不在方法中使用out参数赋值,以及是否有任何方法可以避免这种情况,即通过保留未分配的值而不是显式分配他们null

e.g。你必须写:

public bool OutMethod(out int? output)
{
    output = null;
    return true;
}

或者有办法做类似的事情:

public bool OutMethod(out int? output)
{
    return true;
}

结果相同?

简短的回答是否定的,这是无法避免的。有关包含null明确指定的示例,请参阅the documentation,并声明:

  

请注意,第三个参数指定为null。这允许方法可选地返回值。

此示例也可以在.NET框架中找到。例如Dictionary<TKey,TValue>的{​​{1}}方法:

TryGetValue

请注意public bool TryGetValue(TKey key, out TValue value) { int num = this.FindEntry(key); if (num >= 0) { value = this.entries[num].value; return true; } value = default(TValue); return false; }

的明确分配

答案 3 :(得分:0)

解释很简单:你可以做到。只需将方法内的ou​​t参数指定为所需的值即可。

现在您可以问自己,为什么我们不能在方法签名中这样做?那么,让我们看看正常的可选值参数。如果调用者未分配预定义值,则为它们分配预定义值。因此调用者知道该值,如果未明确设置该参数,则将传递该值。它控制着它,它负责这个决定。

由于方法的调用者不负责out参数的赋值,因此提供默认值是没有意义的。通过使用默认输出参数值,您唯一可以实现的是让调用者知道该out参数的可能值之一。但那会有意义吗?该值何时使用?在什么条件下?所有这些仍然是来自呼叫者隐藏的。因此,除了可以将其设置在签名内而不是方法体中之外,具有可选的out参数值没有任何实际好处。

所以,说到这一点,以下几点没有多大意义:

public bool TrySomething(out string outObject = "default value") { ... }

然而,最好的是允许以下方法

public bool TrySomething(out string outObject) { ... }

按如下方式调用:

bool result = TrySomething();

并且幕后相当于:

string dummyWhichWillNeverBeUsed;
bool succeeded = TrySomething(out dummyWhichWillNeverBeUsed);

不幸的是,这是不允许的。

当然,正如其他答案所解释的那样,你总是可以在没有参数的情况下进行重载。