我在C#深度阅读有关它的部分后,一直在调查C#中的out
关键字。我似乎无法找到一个示例,说明为什么只需要分配return语句的值就需要关键字。例如:
public void Function1(int input, out int output)
{
output = input * 5;
}
public int Function2(int input)
{
return input * 5;
}
...
int i;
int j;
Function1(5, out i);
j = Function2(5);
i和j现在都具有相同的值。是否只是在没有=
符号的情况下进行初始化的便利性,或者是否有其他值得我没有看到?我已经看到一些类似的答案提到它将初始化的责任转移到被调用者here。但是所有这些都是额外的,而不仅仅是分配一个返回值而没有一个void方法签名?
答案 0 :(得分:13)
通常out用于返回其他内容的方法,但您仍需要从方法中获取不同的值。
一个很好的例子是Int32.TryParse(input, out myVar)
如果成功则返回true,否则返回false。您可以通过out参数获取转换后的int。
int myOutVar;
if (Int32.TryParse("2", out myOutVar))
{
//do something with the int
}else{
//Parsing failed, show a message
}
答案 1 :(得分:3)
只有在需要返回多个值时才能使用C#中的out / ref
个关键字。即使这样,在恢复到Tuple
之前,您应该首先考虑使用容器类型(例如out / ref
)来返回多个值。无论何时返回单个值,都应该返回。
答案 2 :(得分:3)
很多时候,使用out
可以帮助您获得轻微的性能提升。
考虑TryGetValue
上的IDictionary
方法(比如myDictionary是IDictionary<string, string>
)而不是这样做:
string value = String.Empty;
if (myDictionary.ContainsKey("foo"))
{
value = myDictionary["foo"];
}
ContainsKey
和索引器都需要查找字典中的键,但是你可以通过以下方式避免在正面情况下进行双重查找:
string value;
if (!myDictionary.TryGetValue("foo", out value))
{
value = String.Empty;
}
IMO,这是使用out
参数的正当理由。
答案 3 :(得分:2)
不幸的是我们在C#中不能做类似下面的事情:
a,b = func(x,y,z);
我们用Python或其他语言做的事情。有点克服了这一点。
我相信F#已经用元组克服了这一点。
PS:从函数中返回多个值可能并不总是好的。微小的类型在大多数时候都很好 - http://www.martinfowler.com/bliki/DataClump.html
答案 4 :(得分:1)
例如,如果Int32.TryParse
正确解析并且out参数更改了值,则0
返回布尔值。如果解析后的值为true
并且返回0
,则表示您发送到解析的值为false
。如果它返回{{1}},则解析器失败。
答案 5 :(得分:1)
其中一些是为了清晰起见。采用TryParse()方法,如
Int32.TryParse("3", out myInt);
这将返回一个bool,指示字符串是否能够被解析为int。 如果你刚才
Int32.TryParse("3", myInt);
当被召唤时会发生什么?我分配了吗? TryParse是否返回int?
这不是很明显。但是,如果我有一个out
参数,那么我知道该值已被分配,并且返回是其他内容。
答案 6 :(得分:1)
基本上你做的事情(我的数据库读取)
if (ReadSingle<UserRecord>(cmd, out user))
Cache.Insert(cacheId, user, null,
DateTime.MaxValue, TimeSpan.FromMinutes(3));
否则你会做类似的事情:
user = ReadSingle<UserRecord>(cmd);
if(null != user)
// Cache.Insert ...
它简化了代码以使用布尔结果(从数据库中读取记录)并通过out
关键字将实际记录输入变量。