(C#) 迭代只读私有集合成员
我有一个类,它有两个 HashSet
集合作为私有成员。我的代码中的其他类希望能够迭代这些 HashSet 并读取它们的内容。我不想编写标准 getter,因为另一个类仍然可以执行诸如 myClass.getHashSet().Clear(); 之类的操作是否有其他方法可以将我的 HashSets 的元素公开给迭代,而无需进行迭代暴露对 HashSet 本身的引用?我希望能够以与 for-each 循环兼容的方式来完成此操作。
I have a class which has two HashSet<String>
collections as private members. Other classes in my code would like to be able to iterate over those HashSets and read their contents. I don't want to write a standard getter because another class could still do something like myClass.getHashSet().Clear();
Is there any other way to expose the elements of my HashSets to iteration without exposing the reference to the HashSet itself? I'd love to be able to do this in a way that is compatible with for-each loops.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
假设您使用的是 .NET 3.5,您自己编写生成代码的一种替代方法是调用 LINQ 方法。例如:
or
有多种 LINQ 运算符可以像这样使用 - 使用
Skip(0)
可能是最有效的,因为在初始“跳过 0 值”循环之后,它可能只是 <其他答案中显示的 code>foreach/yield return
循环。Select
版本将为生成的每个项目调用无操作投影委托。然而,这种差异显着的可能性非常小 - 我建议您选择使代码对您来说最清晰的方式。Assuming you're using .NET 3.5, one alternative to writing the yield code yourself is to call a LINQ method. For example:
or
There are various LINQ operators which could be used like this - using
Skip(0)
is probably the most efficient, as after the initial "skip 0 values" loop, it's probably just theforeach
/yield return
loop shown in the other answers. TheSelect
version will call the no-op projection delegate for each item yielded. The chances of this difference being significant are astronomically small, however - I suggest you go with whatever makes the code clearest to you.公开
IEnumerable
属性:当然,此代码的用户可以将该
IEnumerable
转换为HashSet
并编辑元素,因此为了安全起见(同时会损害性能),您可以执行以下操作:或者:
一种更高效的保护方法,但对调用者来说不太方便,是返回:
IEnumerator
IEnumeratorExpose a
IEnumerable<T>
property:Of course, the user of this code can cast that
IEnumerable<T>
to aHashSet<T>
and edit elements, so to be on the safe side (while hurting performance), you can do:or:
A more performant method of protection, but less convenient to the caller, is to return an
IEnumerator<T>
:添加这样的方法/属性以避免暴露实际容器:
Add a method/property like this to avoid exposing the actual container:
您还可以使用
Select
方法创建一个无法转换回HashSet
的包装器:这可以避免迭代
_values
两次,就像使用.ToArray()
一样,但将实现保持在一个干净的行中。You can also use the
Select
method to create a wrapper than can't be cast back toHashSet<T>
:This avoids iterating over
_values
twice, as you would with.ToArray()
, but keeps the implementation to a single clean line.这对于聚会来说可能有点太晚了,但今天最简单的方法是使用 Linq。 写而不是写
你可以
This might be quite a bit too late to the party but the easiest way today would be to use Linq. Instead of writing
you can write
您还可以提供如下序列:
然后可以在 foreach 循环中调用此方法:
You may also provide a sequence like this:
This method may then be called within a foreach loop:
让您的 getter 将 HashSet 公开为 IEnumerable。
如果泛型类型是可变的,那么仍然可以修改它,但不能在 HashSet 中添加或删除任何项目。
Make your getter expose the HashSet as IEnumerable.
If the generic type is mutable, then that can still be modified, but no items can be added or removed from your HashSet.