我有一个类有两个HashSet<String>
个集合作为私有成员。我的代码中的其他类希望能够迭代这些HashSets并读取它们的内容。我不想写一个标准的getter,因为另一个类仍然可以做类似myClass.getHashSet().Clear();
的事情。是否有其他方法可以将HashSets的元素暴露给迭代而不暴露对HashSet本身的引用?我希望能够以与for-each循环兼容的方式执行此操作。
答案 0 :(得分:6)
假设您使用的是.NET 3.5,那么自己编写yield代码的另一种方法是调用LINQ方法。例如:
public IEnumerable<string> HashSet
{
get { return privateMember.Select(x => x); }
}
或
public IEnumerable<string> HashSet
{
get { return privateMember.Skip(0); }
}
有各种LINQ运算符可以像这样使用 - 使用Skip(0)
可能是最有效的,因为在初始的“skip 0 values”循环之后,它可能只是foreach
/ {{ 1}}循环显示在其他答案中。 yield return
版本将为每个产生的项目调用no-op投影委托。这种差异很大的可能性很小,但是 - 我建议你选择使代码最清晰的东西。
答案 1 :(得分:3)
公开IEnumerable<T>
财产:
public IEnumerable<whatevertype> MyHashSet {
get {
return this.myHashSet;
}
}
当然,此代码的用户可以将IEnumerable<T>
强制转换为HashSet<T>
并编辑元素,因此为了安全起见(同时损害性能),您可以执行以下操作:
public IEnumerable<whatevertype> MyHashSet {
get {
return this.myHashSet.ToArray();
}
}
或:
public IEnumerable<whatevertype> MyHashSet {
get {
foreach(var item in this.myHashSet) {
yield return item;
}
}
}
更有效的保护方法,但对来电者来说不太方便,就是返回IEnumerator<T>
:
public IEnumerator<whatevertype> GetMyHashSetEnumerator() {
return this.myHashSet.GetEnumerator();
}
答案 2 :(得分:3)
添加这样的方法/属性以避免暴露实际容器:
public IEnumerable EnumerateFirst()
{
foreach( var item in hashSet )
yield return item;
}
答案 3 :(得分:3)
您还可以使用Select
方法创建一个包装,而不能转换回HashSet<T>
:
public IEnumerable<int> Values
{
get { return _values.Select(value => value);
}
这样可以避免迭代_values
两次,就像.ToArray()
一样,但是将实现保持在一条干净的线上。
答案 4 :(得分:0)
您也可以提供如下序列:
public IEnumerable<string> GetHashSetOneValues()
{
foreach (string value in hashSetOne)
yield return value;
}
然后可以在foreach循环中调用此方法:
foreach (string value in myObject.GetHashSetOneValues())
DoSomething(value);
答案 5 :(得分:0)
这可能对派对来说太晚了,但今天最简单的方法就是使用Linq。而不是写
public IEnumerable<string> GetValues()
{
foreach(var elem in list)
yield return elem;
}
你可以写
public IEnumerable<string> GetValues() => list;
答案 6 :(得分:-1)
让你的getter将HashSet公开为IEnumerable。
private HashSet<string> _mine;
public IEnumerable<string> Yours
{
get { return _mine; }
}
如果泛型类型是可变的,那么仍然可以修改它,但是不能在HashSet中添加或删除任何项目。