为什么 "out" 参数作为语言结构存在于 C# 中?
Why does the "out" parameter exist in C# as a language construct?
问题
为什么 "out" 参数作为语言结构存在于 C# 中?
问题的详细说明
为什么它首先存在?难道没有更好的语言特性来获得与 "out" 参数相同的效果吗?
让值类型表现得像引用类型是不是很奇怪?
难道没有更好的方法 return 从一个方法中获取多个值吗?
这是一个历史问题吗,这意味着在第一个版本的 C# 中,无法实现使用 out 参数可以实现的功能,但现在有更新的功能,它只是为了向后兼容而保留在语言中?
我没有问什么
- 我不是问它做什么
- 我不是问怎么用的
- What is the purpose of the "out" keyword at the caller (in C#)?
- 我不是问 "ref" 和 "out" 有什么区别
- What's the difference between the 'ref' and 'out' keywords?
- 我读到应该避免使用它并选择其他结构
- Best practice of using the "out" keyword in C#
我在阅读类似问题时没有发现任何重复问题。
预期答案格式
我很想听到这样的话,“看,这是一个只能使用 "out" 参数语言构造才能解决的问题,这是它的代码示例...” .
或者,"Look, this used to be the only way to solve the following problem ...code example..., but since C# version ... the better way to solve is like this ... code example...".
没有意见请。
一个原因是为了兼容,例如。 Win32 APIs。 Win32 API 调用的某些方法声明将需要使用 out and/or ref 如果您想直接从 C# 调用它们。
您可以在 pinvoke.net 中找到此类方法声明的一些示例:
http://pinvoke.net/search.aspx?search=out&namespace=[All]
Why does it exist in the first place? Aren't there better language features to get the same effect one can get with the "out" parameter?
什么是 "better"?基于 C#7 的争论,其中事情更容易一些,是这样的:
public static (bool Succesful, int Value) TryParse(string s) { ... }
var parseResult = TryParse(s);
if (parResult.Succesful)
DoSomething(parResult.Result);
优于?
if (int.TryParse(s, out var i))
DoSomething(i);
嗯嗯....
在本机元组支持之前,您实际上必须实现一个 struct/class 才能 return 多个值...。诚然,out
解决方案也不会那么干净,但仍然是一个更好的选择,而不是必须在代码库中乱扔大量轻量级容器 类 来简单地拥有方法 return 多个值.
Isn't it strange to make an value type behave like a reference type?
为什么?即使它只是为了向后兼容或互操作,它也是一个必需的语言特性。
还有,你搞混了。如果你想通过引用语义传递,你会使用 ref
关键字。 out
关键字表示该参数将用作 return 值;它需要通过引用传递的事实是一个实现细节。
Aren't there better ways to return multiple values from a method?
这基本上是您重写的第一个问题。
Is it a historical thing, meaning with the first versions of C# there was no way to achieve the things one can achieve with the out parameter but now there are newer features and it's just kept in the language for backwards compatibility?
向后兼容性是显而易见的重要原因。此外,仅仅因为有更好的方法来做事并不一定意味着应该删除语言功能。然后,您可以为许多其他语言构造提供案例:for
循环、goto
等。
C# 编译器执行 definite assignment checking。这要求它确切地知道何时分配变量。通常不难弄清楚,作业很容易看回来。
但是有一个极端情况是当一个变量通过引用传递给另一个方法时。该方法是否要求在调用之前分配该变量,然后修改它,或者它只是要分配它?编译器通常不知道,该方法可能存在于另一个方法体不可用的程序集中。例如,对于任何 .NET Framework 程序集都是如此。
所以你必须明确说明,当方法需要在调用之前分配参数时使用 ref
,当方法只分配参数时使用 out
。顺便说一句,很棒的功能,它消除了一大堆非常常见的错误。
关于此问题的其他错误答案的注释。数据流在 pinvoke 中也起着重要作用,pinvoke 编组器需要知道是否转换了非托管函数返回的任何数据。它 不 关注 out vs ref 关键字,只关注 [In]
和 [Out]
属性。更多关于 .
中的细节
问题
为什么 "out" 参数作为语言结构存在于 C# 中?
问题的详细说明
为什么它首先存在?难道没有更好的语言特性来获得与 "out" 参数相同的效果吗?
让值类型表现得像引用类型是不是很奇怪?
难道没有更好的方法 return 从一个方法中获取多个值吗?
这是一个历史问题吗,这意味着在第一个版本的 C# 中,无法实现使用 out 参数可以实现的功能,但现在有更新的功能,它只是为了向后兼容而保留在语言中?
我没有问什么
- 我不是问它做什么
- 我不是问怎么用的
- What is the purpose of the "out" keyword at the caller (in C#)?
- 我不是问 "ref" 和 "out" 有什么区别
- What's the difference between the 'ref' and 'out' keywords?
- 我读到应该避免使用它并选择其他结构
- Best practice of using the "out" keyword in C#
我在阅读类似问题时没有发现任何重复问题。
预期答案格式
我很想听到这样的话,“看,这是一个只能使用 "out" 参数语言构造才能解决的问题,这是它的代码示例...” .
或者,"Look, this used to be the only way to solve the following problem ...code example..., but since C# version ... the better way to solve is like this ... code example...".
没有意见请。
一个原因是为了兼容,例如。 Win32 APIs。 Win32 API 调用的某些方法声明将需要使用 out and/or ref 如果您想直接从 C# 调用它们。
您可以在 pinvoke.net 中找到此类方法声明的一些示例: http://pinvoke.net/search.aspx?search=out&namespace=[All]
Why does it exist in the first place? Aren't there better language features to get the same effect one can get with the "out" parameter?
什么是 "better"?基于 C#7 的争论,其中事情更容易一些,是这样的:
public static (bool Succesful, int Value) TryParse(string s) { ... }
var parseResult = TryParse(s);
if (parResult.Succesful)
DoSomething(parResult.Result);
优于?
if (int.TryParse(s, out var i))
DoSomething(i);
嗯嗯....
在本机元组支持之前,您实际上必须实现一个 struct/class 才能 return 多个值...。诚然,out
解决方案也不会那么干净,但仍然是一个更好的选择,而不是必须在代码库中乱扔大量轻量级容器 类 来简单地拥有方法 return 多个值.
Isn't it strange to make an value type behave like a reference type?
为什么?即使它只是为了向后兼容或互操作,它也是一个必需的语言特性。
还有,你搞混了。如果你想通过引用语义传递,你会使用 ref
关键字。 out
关键字表示该参数将用作 return 值;它需要通过引用传递的事实是一个实现细节。
Aren't there better ways to return multiple values from a method?
这基本上是您重写的第一个问题。
Is it a historical thing, meaning with the first versions of C# there was no way to achieve the things one can achieve with the out parameter but now there are newer features and it's just kept in the language for backwards compatibility?
向后兼容性是显而易见的重要原因。此外,仅仅因为有更好的方法来做事并不一定意味着应该删除语言功能。然后,您可以为许多其他语言构造提供案例:for
循环、goto
等。
C# 编译器执行 definite assignment checking。这要求它确切地知道何时分配变量。通常不难弄清楚,作业很容易看回来。
但是有一个极端情况是当一个变量通过引用传递给另一个方法时。该方法是否要求在调用之前分配该变量,然后修改它,或者它只是要分配它?编译器通常不知道,该方法可能存在于另一个方法体不可用的程序集中。例如,对于任何 .NET Framework 程序集都是如此。
所以你必须明确说明,当方法需要在调用之前分配参数时使用 ref
,当方法只分配参数时使用 out
。顺便说一句,很棒的功能,它消除了一大堆非常常见的错误。
关于此问题的其他错误答案的注释。数据流在 pinvoke 中也起着重要作用,pinvoke 编组器需要知道是否转换了非托管函数返回的任何数据。它 不 关注 out vs ref 关键字,只关注 [In]
和 [Out]
属性。更多关于