传递HashSet<;字符串>;通过引用
本文关键字:引用 gt 字符串 lt 传递 HashSet | 更新日期: 2023-09-27 18:25:47
是否可以通过引用函数来传递HashSet?这是我当前的代码。
主
this.scrapeFriends(startUsers, userIDs, 100);
功能
private void scrapeFriends(StringCollection startUsers, ref HashSet<string> userIDs, int p)
{
// Do something
}
如果我删除引用,它就起作用了。如果我添加它,它就不会编译。
您总是通过引用传递HashSet<T>
,因为它是引用类型。
ref
关键字用于通过引用传递变量。
基本上:
- 无论是否使用
ref
,都可以更改HashSet<T>
的内容 - 使用
ref
关键字,可以将HashSet<T>
实例替换为不同的实例,并让调用代码注意到这一点(您正在修改传递给方法的变量) - 如果没有
ref
关键字,如果用不同的实例替换实例,则该更改仅在被调用的方法内部有效,调用它的代码仍然具有旧引用
代码不编译的原因是,如果您将方法的参数设置为ref
参数,则还必须使用ref
关键字来调用它,因此将调用代码更改为:
this.scrapeFriends(startUsers, ref userIDs, 100);
^^^
|
+-- add this
为了进行编译,您需要在调用站点添加ref
this.scrapeFriends(startUsers, ref userIDs, 100);
但是我想问你为什么这么做?HashSet<T>
是.Net中的引用类型,因此它的副本不会传递给每个函数。每个函数将引用相同的HashSet<T>
实例(但通过引用的不同副本)。ref
导致引用通过引用传递,这在这里几乎肯定不需要
在少数情况下,您需要通过引用传递可变引用类型(如HashSet<T>
)。你确定这是其中之一吗?特别地,该方法可以在不使用ref
的情况下向集合添加新项目。如果您想首先更改该点的设置,则只需要ref
。你不太可能想要在这里。
代码不编译的原因是,对于ref
参数,您还需要在调用站点指定ref
:
this.scrapeFriends(startUsers, ref userIDs, 100);
但正如我所说,你不太可能想要这个。
如其他答案中所述,为了确保代码可编译,您需要在调用站点添加ref
,如下所示。
this.scrapeFriends(startUsers, ref userIDs, 100);
为了提供更多的上下文,HashSet是C#中的一个引用类型。当您将其传递给不带ref的方法时,会传递存储HashSet的内存位置的地址。这使您只能从HashSet中添加/删除元素。
但是,当您在调用方法时使用ref
时,会传递存储变量的位置的内存地址。这允许您将变量指向一个新位置,即创建一个HashSet的新实例并对其进行操作。