Dun*_*unc 187

没有.

解决方法是使用另一个没有 out/ref参数的方法重载,并且只调用当前方法.

public bool SomeMethod(out string input)
{
    ...
}

// new overload
public bool SomeMethod()
{
    string temp;
    return SomeMethod(out temp);
}
Run Code Online (Sandbox Code Playgroud)

更新:如果你有C#7.0,你可以简化:

// new overload
public bool SomeMethod()
{
    return SomeMethod(out _);    // declare out as an inline discard variable
}
Run Code Online (Sandbox Code Playgroud)

(感谢@Oskar/@Reiner指出这一点.)

  • 也许体面,但优雅绝对是另一个联盟.事实上没有更好的解决方案并不意味着这是最先进的法令. (26认同)
  • 有什么不优雅的?看起来对我很不错. (20认同)
  • 有什么想法比宣布temp/dummy更优雅的解决方案? (6认同)
  • 抓住@ o0'.在C#7.0中,您将能够执行此操作:`return SomeMethod(out string temp)`.在此处查看更多信息:https://blogs.msdn.microsoft.com/dotnet/2016/08/24/whats-new-in-csharp-7-0/#user-content-out-variables (6认同)
  • 在C#7.0中,您可以使用临时的只写变量,如:`return SomeMethod(out _);` (6认同)

Tom*_*cek 90

如前所述,这是不允许的,我认为它非常有意义.但是,要添加更多详细信息,请参阅C#4.0规范第21.1节中的引用:

构造函数,方法,索引器和委托类型的形式参数可以声明为可选:

fixed-parameter:
    attributes opt参数-modifier opt type identifier default-argument opt
default-argument:
    = expression

  • 固定参数默认参数的是一个可选参数,而一个固定参数没有缺省参数的是一个必需的参数.
  • formal-parameter-list中的可选参数之后,不能显示必需参数.
  • 一个refout参数不能有default-argument.


Rob*_*n R 63

不,但另一个很好的选择是让方法使用通用模板类作为可选参数,如下所示:

public class OptionalOut<Type>
{
    public Type Result { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

然后你可以使用它如下:

public string foo(string value, OptionalOut<int> outResult = null)
{
    // .. do something

    if (outResult != null) {
        outResult.Result = 100;
    }

    return value;
}

public void bar ()
{
    string str = "bar";

    string result;
    OptionalOut<int> optional = new OptionalOut<int> ();

    // example: call without the optional out parameter
    result = foo (str);
    Console.WriteLine ("Output was {0} with no optional value used", result);

    // example: call it with optional parameter
    result = foo (str, optional);
    Console.WriteLine ("Output was {0} with optional value of {1}", result, optional.Result);

    // example: call it with named optional parameter
    foo (str, outResult: optional);
    Console.WriteLine ("Output was {0} with optional value of {1}", result, optional.Result);
}
Run Code Online (Sandbox Code Playgroud)

  • 这是一个非常合理的解决方案,但有一点需要注意的是编译器不会强制要求在退出方法之前分配out参数. (19认同)
  • 我喜欢它,但是如果你不想创建一个新类,你可以通过传入一个单独的元素数组来模拟它. (2认同)

wiz*_*KSU 28

实际上有一种方法可以做到这一点,C#允许这样做.这回到了C++,而是违反了C#的面向对象的优秀结构.

小心使用这种方法!

以下是使用可选参数声明和编写函数的方法:

unsafe public void OptionalOutParameter(int* pOutParam = null)
{
    int lInteger = 5;
    // If the parameter is NULL, the caller doesn't care about this value.
    if (pOutParam != null) 
    { 
        // If it isn't null, the caller has provided the address of an integer.
        *pOutParam = lInteger; // Dereference the pointer and assign the return value.
    }
}
Run Code Online (Sandbox Code Playgroud)

然后像这样调用函数:

unsafe { OptionalOutParameter(); } // does nothing
int MyInteger = 0;
unsafe { OptionalOutParameter(&MyInteger); } // pass in the address of MyInteger.
Run Code Online (Sandbox Code Playgroud)

为了使其编译,您需要在项目选项中启用不安全的代码.这是一个非常hacky的解决方案,通常不应该使用,但如果你做一些奇怪的,神秘的,神秘的,管理启发的决定,真的需要在C#中选择out参数,那么这将允许你做到这一点.

  • "受管理启发"=来自迪尔伯特的尖头发老板. (10认同)

小智 6

ICYMI:包含在此处枚举的C#7.0的新功能中," discards "现在允许作为_形式的out参数,让您忽略掉您不关心的参数:

p.GetCoordinates(out var x, out _); // I only care about x

PS如果你也对"out var x"部分感到困惑,请阅读链接上关于"Out Variables"的新功能.


Ste*_*eve 5

不,但您可以使用委托(例如Action)作为替代方案。

当我遇到我认为我需要一个可选的输出参数的情况时,部分受到 Robin R 的回答的启发,我改为使用委托Action。我借用了他的示例代码进行修改以供使用Action<int>,以显示差异和相似之处:

public string foo(string value, Action<int> outResult = null)
{
    // .. do something

    outResult?.Invoke(100);

    return value;
}

public void bar ()
{
    string str = "bar";

    string result;
    int optional = 0;

    // example: call without the optional out parameter
    result = foo (str);
    Console.WriteLine ("Output was {0} with no optional value used", result);

    // example: call it with optional parameter
    result = foo (str, x => optional = x);
    Console.WriteLine ("Output was {0} with optional value of {1}", result, optional);

    // example: call it with named optional parameter
    foo (str, outResult: x => optional = x);
    Console.WriteLine ("Output was {0} with optional value of {1}", result, optional);
}
Run Code Online (Sandbox Code Playgroud)

这样做的优点是可选变量在源代码中显示为普通 int (编译器将其包装在闭包类中,而不是我们将其显式包装在用户定义的类中)。

该变量需要显式初始化,因为编译器无法假设该变量Action将在函数调用退出之前被调用。

它并不适合所有用例,但对于我的实际用例(一个为单元测试提供数据的函数,以及新的单元测试需要访问返回值中不存在的某些内部状态的函数)效果很好。