C#4.0是否允许可选的out
或ref
参数?
答案 0 :(得分:178)
没有
解决方法是使用不具有out / ref参数的另一种方法重载,并且只调用当前方法。
public bool SomeMethod(out string input)
{
...
}
// new overload
public bool SomeMethod()
{
string temp;
return SomeMethod(out temp);
}
更新:如果您有C# 7.0,则可以简化:
// new overload
public bool SomeMethod()
{
return SomeMethod(out _); // declare out as an inline discard variable
}
(感谢@Oskar / @Reiner指出这一点。)
答案 1 :(得分:86)
正如已经提到的,这是不允许的,我认为这是非常有意义的。 但是,要添加更多详细信息,请参阅C# 4.0 Specification第21.1节中的引用:
构造函数,方法,索引器和委托类型的形式参数可以声明为可选:
固定参数:
attributes opt parameter-modifier opt type identifier default-argument opt
默认参数:
=表达
- 带有默认参数的固定参数是可选参数,而固定参数没有默认参数是必需参数。
- formal-parameter-list 中的可选参数后,无法显示必需参数。
ref
或out
参数不能包含默认参数。
答案 2 :(得分:61)
不,但另一个很好的选择是让方法使用通用模板类作为可选参数,如下所示:
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);
}
答案 3 :(得分:26)
实际上有一种方法可以做到这一点,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.
}
}
然后调用这个函数:
unsafe { OptionalOutParameter(); } // does nothing
int MyInteger = 0;
unsafe { OptionalOutParameter(&MyInteger); } // pass in the address of MyInteger.
为了使其编译,您需要在项目选项中启用不安全的代码。这是一个通常不应该使用的真正hacky解决方案,但是如果你做一些奇怪的,神秘的,神秘的,管理启发的决定,真的需要在C#中选择out参数,那么这将允许你这样做
答案 4 :(得分:5)
ICYMI:包含在C#7.0枚举here的新功能中,“丢弃”现在允许作为_形式的输出参数,让您忽略不关心的参数:< / p>
p.GetCoordinates(out var x, out _); // I only care about x
P.S。如果您还对“out var x”部分感到困惑,请阅读链接上有关“Out Variables”的新功能。
答案 5 :(得分:1)
不,但您可以使用代理人(例如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);
}
这样做的好处是,可选变量作为普通的int出现在源代码中(编译器将它包装在一个闭包类中,而不是将它显式地包装在用户定义的类中)。
变量需要显式初始化,因为编译器不能假定在函数调用退出之前调用Action
。
它不适合所有用例,但适用于我的实际用例(为单元测试提供数据的函数,以及新单元测试需要访问返回值中不存在的某个内部状态的函数)。
答案 6 :(得分:0)
对于C#6.0及更低版本,请使用没有out参数的重载方法来调用带有out参数的方法。我不确定为什么当专门询问C#4.0是否可以具有可选的out参数时,为什么.NET Core的C#7.0甚至是此线程的正确答案。答案是否定的!
答案 7 :(得分:-2)
这样怎么样?
public bool OptionalOutParamMethod([Optional] ref string pOutParam)
{
return true;
}
您仍然必须将值传递给C#中的参数,但它是一个可选的参数参数。
答案 8 :(得分:-4)
expand_aliases