c# 4.0允许可选的out或ref参数吗?
当前回答
正如已经提到的,这是不允许的,我认为这是非常有意义的。 然而,为了增加更多的细节,这里引用了c# 4.0规范21.1节:
Formal parameters of constructors, methods, indexers and delegate types can be declared optional: fixed-parameter: attributesopt parameter-modifieropt type identifier default-argumentopt default-argument: = expression A fixed-parameter with a default-argument is an optional parameter, whereas a fixed-parameter without a default-argument is a required parameter. A required parameter cannot appear after an optional parameter in a formal-parameter-list. A ref or out parameter cannot have a default-argument.
其他回答
不是,但是另一个很好的替代方法是让方法使用一个泛型模板类来处理可选参数,如下所示:
public class OptionalOut<Type>
{
public Type Result { get; set; }
}
那么你可以这样使用它:
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);
}
正如已经提到的,这是不允许的,我认为这是非常有意义的。 然而,为了增加更多的细节,这里引用了c# 4.0规范21.1节:
Formal parameters of constructors, methods, indexers and delegate types can be declared optional: fixed-parameter: attributesopt parameter-modifieropt type identifier default-argumentopt default-argument: = expression A fixed-parameter with a default-argument is an optional parameter, whereas a fixed-parameter without a default-argument is a required parameter. A required parameter cannot appear after an optional parameter in a formal-parameter-list. A ref or out parameter cannot have a default-argument.
对于c# 6.0及以下版本,使用不带out形参的重载方法调用带out形参的方法。当被特别问到c# 4.0是否可以有一个可选的out参数时,我不确定为什么用于。net Core的c# 7.0甚至是这个线程的正确答案。答案是否定的!
不,但你可以使用委托(例如Action)作为替代。
当我想要一个可选的out参数时,部分受到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);
}
这样做的好处是,可选变量在源代码中作为普通int出现(编译器将其包装在闭包类中,而不是我们显式地将其包装在用户定义的类中)。
变量需要显式初始化,因为编译器不能假定Action将在函数调用退出之前被调用。
它并不适合所有的用例,但是对于我的实际用例(一个为单元测试提供数据的函数,并且一个新的单元测试需要访问一些没有在返回值中出现的内部状态)来说效果很好。
ICYMI:包括在这里列举的c# 7.0的新特性中,“discards”现在被允许以_的形式作为out参数,让你忽略你不关心的out参数:
p.GetCoordinates(out var x, out _);//我只关心x
附注:如果你也对“输出变量x”的部分感到困惑,请阅读链接上关于“输出变量”的新功能。
推荐文章
- c# 4.0可选的out/ref参数
- c# 4.0中的“动态”类型是用来干什么的?
- 平行的。ForEach vs Task.Factory.StartNew
- 动态地向ExpandoObject添加属性
- x = x || y是什么意思?
- 在Tuple类中比"Item1", "Item2"更好的命名
- 普通参数与关键字参数
- .NET NewtonSoft JSON反序列化映射到不同的属性名
- 可选关键字参数的命名元组和默认值
- 如何定义具有可选参数的函数?
- 是否有一种方法在JavaScript函数调用中提供命名参数?
- 为什么在接口上定义的c# 4可选参数没有强制实现类?
- 如何在Swift协议中声明可选方法?
- 任务和线程的区别是什么?
- 如何在c#中使用可选参数?