为了账号安全,请及时绑定邮箱和手机立即绑定

为什么“out”参数作为语言结构存在于 C# 中?

为什么“out”参数作为语言结构存在于 C# 中?

C#
繁花如伊 2022-01-15 19:24:50
问题为什么“out”参数作为语言结构存在于 C# 中?关于问题的详细说明为什么它首先存在?难道没有更好的语言特性来获得与“out”参数相同的效果吗?让值类型表现得像引用类型不是很奇怪吗?没有更好的方法从一个方法返回多个值吗?这是一个历史性的事情吗,这意味着对于 C# 的第一个版本,没有办法实现使用 out 参数可以实现的东西,但现在有更新的功能,它只是保留在语言中以实现向后兼容性?我不是在问什么我不是在问它做什么out 参数修饰符(C# 参考)我不是问它是如何使用的https://stackoverflow.com/a/8128838/33311调用者(在 C# 中)的“out”关键字的目的是什么?我不是在问“ref”和“out”之间的区别是什么'ref' 和 'out' 关键字有什么区别?我读到应该避免使用它并选择其他构造在 C# 中使用“out”关键字的最佳实践在阅读类似问题时,我没有发现任何重复项。预期答案格式我很想听到类似“看,这是一个只能使用“out”参数语言结构才能解决的问题,这是一个代码示例……”。或者,“看,这曾经是解决以下问题的唯一方法......代码示例......,但由于 C# 版本......更好的解决方法是这样......代码示例......” .请不要发表意见。
查看完整描述

3 回答

?
RISEBY

TA贡献1856条经验 获得超5个赞

C# 编译器执行明确的赋值检查。这要求它准确知道何时分配变量。通常不难弄清楚,一项任务很容易看到。

但是有一个极端情况是当一个变量通过引用传递给另一个方法时。该方法是否要求在调用之前分配该变量,然后对其进行修改,还是只分配它?编译器通常无法知道,该方法可能存在于另一个程序集中,而方法主体不可用。例如,对于任何 .NET Framework 程序集都是如此。

所以你必须明确它,ref当方法需要在调用之前分配参数时使用,out当方法只分配它时。顺便说一句,很棒的功能,它消除了整个非常常见的错误。


关于此问题的其他不正确答案的注释。数据流在 pinvoke 中也起着重要作用,pinvoke 编组器需要知道是否转换了非托管函数返回的任何数据。它不关注out vs ref 关键字,只关注[In]and[Out]属性。更多关于这个 Q+A中的细节。


查看完整回答
反对 回复 2022-01-15
?
蓝山帝景

TA贡献1843条经验 获得超7个赞

一个原因是为了与例如 Win32 API 的兼容性。如果您想直接从 C# 调用 Win32 API 调用的某些方法声明,则需要使用 out 和/或 ref。

您可以在 pinvoke.net 找到此类方法声明的一些示例: http://pinvoke.net/search.aspx?search=out&namespace=[All]


查看完整回答
反对 回复 2022-01-15
?
HUH函数

TA贡献1836条经验 获得超4个赞

为什么它首先存在?难道没有更好的语言特性来获得与“out”参数相同的效果吗?


什么是“更好”?基于 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);

嗯……


在原生元组支持之前,您实际上必须实现一个结构/类才能返回多个值……哎呀。确实,该out解决方案也不会那么干净,但仍然是一个更好的选择,而不是必须用大量轻量级容器类乱扔代码库来简单地让方法返回多个值。


让值类型表现得像引用类型不是很奇怪吗?


为什么?即使它只是为了向后兼容或互操作,它也是一个需要的语言特性。


另外,你在这里混淆了东西。如果你想通过引用语义传递,你会使用ref关键字。关键字表示该out参数旨在用作返回值;它需要通过引用传递的事实是一个实现细节。


没有更好的方法从一个方法返回多个值吗?


这基本上是你重写的第一个问题。


这是一个历史性的事情吗,这意味着对于 C# 的第一个版本,没有办法实现使用 out 参数可以实现的东西,但现在有更新的功能,它只是保留在语言中以实现向后兼容性?


向后兼容是显而易见的重要原因。此外,仅仅因为有更好的方法来做事并不一定意味着应该删除语言功能。然后,您可以为许多其他语言构造提供一个案例:for循环goto,等等。


查看完整回答
反对 回复 2022-01-15
  • 3 回答
  • 0 关注
  • 165 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信