C# 为什么部分方法可以使用 ref,但不能使用 out?
非常简单。 MSDN 声明您可以使用 ref,但不能使用 out 对于部分方法。我只是好奇为什么?据我了解,编译代码时,部分代码会被合并,那么限制是怎么回事呢? partial
除了使代码文件更干净、更有组织(即养眼)之外,还有其他作用吗?
Pretty straight forward. MSDN states that you can use ref, but not out for partial methods. I'm just curious as to the why? It was my understanding that when code is compiled, the partials are merged, so what is up with the restriction? Is there more to partial
than just making code files cleaner and organized (i.e. eyecandy)?
Reference: MSDN Article - "Partial methods can have ref but not out parameters."
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
您必须考虑如果未实现部分方法会发生什么。
然后发生的事情是,对该方法的所有调用都被删除,就好像它们从未发生过一样。
因此,对于使用 out 的方法,它看起来像这样:
并被编译为好像这样说:
不允许使用此代码,因为
s
尚未初始化。当您尝试调用变量的Write
方法时,变量将被初始化的保证与对GetStream
的调用紧密相关。返回数据的方法也是如此。由于如果您没有实现部分方法,则整个方法调用不会被编译,因此您需要考虑可以做什么和不能做什么,并且仍然保留调用它的代码有效。就
out
和返回值而言,它有可能导致调用代码无效或不完整,因此是不允许的。至于
ref
,这是有效的,因为初始化已由调用代码处理:You got to consider what happens if the partial method isn't implemented.
What happens then is that all calls to the method is just stripped out as though they never happened.
So for a method using out, it would look like this:
and be compiled as though it said this:
This code is not allowed because
s
has not been initialized. The guarantee that the variable would be initialized by the time you try to call theWrite
method on it was tied up with the call toGetStream
.It is the same with methods returning data. Since the entire method call is just not compiled if you haven't implemented the partial method, you need to consider what you can and cannot do and still leave the code that calls it valid. In terms of
out
and return values, it has the potential of leaving the calling code invalid or incomplete, so it is not allowed.As for
ref
, that is valid since the initialization has been taken care of by the calling code:因为与 ref 参数不同,out 参数必须在方法返回之前初始化。如果部分方法没有实现(这是一个有效的场景),它如何初始化?
Because unlike ref parameters, out parameters MUST be initialized before the method returns. If the partial method is not implemented (which is a valid scenario,) how can it be initialized?
我的猜测是因为
out
参数不需要初始化,而ref
参数则需要初始化。如果您在部分方法上使用
out
参数,C# 如何验证该参数是否已初始化?My guess would be because
out
parameters don't need to be initialized whereasref
parameters do.If you used an
out
parameter on a partial method, how could C# verify that the parameter was initialized or not?out
参数表明您想要从该方法中获取一个值。如果该方法不存在,则无法提供该值。另一种方法是将变量的值显式设置为其默认值(0、null 等),而不是执行方法调用。这样,变量仍然会被明确初始化 - 尽管默认值可能不是非常有用。我相信 C# 团队已经考虑过这一点 - 甚至可能将其纳入未来版本,谁知道呢?我个人怀疑它是否特别有用,但可能性是存在的。
目前,您始终可以使用 ref 参数,只需在调用默认值之前手动初始化变量即可。
An
out
parameter suggests that you want a value out of the method. If the method doesn't exist, it can't provide that value.The alternative would be to set the variable's value explicitly to its default value (0, null etc) instead of executing the method call. That way the variable would still be definitely initialized - although the default value may not be a terribly useful one. I believe the C# team have considered this - it may even make it into a future version, who knows? Personally I doubt that it would be particularly useful, but the possibility is there.
For the moment, you could always use a
ref
parameter instead, and just initialize the variable manually before the call to whatever the default value should be.我认为原因是因为只有签名(即没有实现)的部分方法仍然有效。如果你有一个 out 参数,那么无实现的方法总是会导致错误(因为没有任何东西分配 out 值)
I would assume the reason is because a partial method with only a signature (i.e. no implementation) is still valid. If you had an out parameter an implementation-less method would always cause an error (as there's nothing assigning the out value)
分部方法分为分部类。需要一种方法来为 OUT 参数赋值。部分方法可能会也可能不会被实现。这意味着多个代码块正在尝试为 OUT 参数赋值。
A partial method is split across partial classes. A method is required to assign a value to an OUT parameter. Partial methods may or may not be implemented. It would mean multiple code chunks is trying to assign value to the OUT parameter.
正如其他人所说,必须分配
out
参数。添加此选项将生成编译器错误 CS0177 <另一方面,code>ref 必须在调用之前进行分配。As everyone else has stated
out
params must be assigned. To add this will generate compiler error CS0177ref
on the other hand must be assigned prior to making the call.