为什么部分类方法可以使用 ref,但不能使用 out?

19
很简单。MSDN指出,您可以使用ref,但不是out来进行部分类方法。我只是好奇为什么?我的理解是,在编译代码时,部分内容会被合并,那么限制是什么?partial除了使代码文件更清洁和有组织外,还有更多的作用吗?
参考资料:MSDN文章 - "部分类方法可以具有ref但不能具有out参数。"
7个回答

21

你必须考虑如果未实现部分类方法会发生什么。

那么,所有对该方法的调用都会被剥离,就好像它们从未发生过一样。

因此,对于一个使用out的方法,它将如下所示:

stream s;
GetStream(out s);
s.Write(...);

并且它会被编译,就像它说的一样:

stream s;
s.Write(...);

这段代码不被允许是因为变量s没有初始化。变量在调用Write方法之前被初始化的保证与调用GetStream方法绑定在一起。

对于返回数据的方法也是一样的。由于如果你没有实现部分方法,整个方法调用将无法编译,因此你需要考虑在哪些情况下可以操作,以使调用方法的代码仍然有效。对于out和返回值,可能会使调用代码无效或不完整,因此不允许使用。

至于ref,那是有效的,因为变量的初始化已经由调用代码处理:

stream s = null;
GetStream(ref s); // may be stripped out
if (s != null)
    s.Write(...);

9

因为与 ref 参数不同,out 参数必须在方法返回之前进行初始化。如果未实现部分类方法(这是一种有效的情况),那么它如何被初始化呢?


未初始化的值类型在C#编译器中是不合法的。请提供一个好的解释。 - Ayub

4

我猜是因为out参数不需要初始化,而ref参数需要。

如果在部分类中使用out参数,C#如何验证参数是否已经被初始化呢?


4
一个out参数意味着你希望从方法中获取一个值。如果该方法不存在,则无法提供该值。
另一种方法是将变量的值明确设置为其默认值(0、null等),而不是执行方法调用。这样,变量仍然被明确定义 - 尽管默认值可能不是非常有用的值。我认为C#团队已经考虑过这个问题了 - 也许它会出现在未来的版本中,谁知道呢?个人认为它并不特别有用,但这种可能性是存在的。
目前,您可以始终使用ref参数,并在调用默认值之前手动初始化变量。

1
我认为原因是因为只有签名(即没有实现)的部分类方法仍然有效。如果您有一个输出参数,那么没有实现的方法将始终导致错误(因为没有任何东西分配输出值)。

1

部分类中分割的部分方法。需要一个方法来为OUT参数分配值。部分方法可以实现,也可以不实现。这意味着多个代码块正在尝试为OUT参数分配值。


1

正如其他人所说,out参数必须被赋值。如果添加此代码将会生成编译器错误 CS0177 另一方面,ref参数在调用之前必须被赋值。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接