2

我有一个有两个HashSet<String>集合作为私有成员的类。我的代码中的其他类希望能够遍历这些 HashSet 并读取它们的内容。我不想写一个标准的getter,因为另一个类仍然可以做类似的事情myClass.getHashSet().Clear(); 有没有其他方法可以将我的HashSets的元素暴露给迭代而不暴露对HashSet本身的引用?我希望能够以与 for-each 循环兼容的方式执行此操作。

4

7 回答 7

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 运算符可以像这样使用 - usingSkip(0)可能是最有效的,因为在初始“跳过 0 值”循环之后,它可能只是其他答案中显示的foreach/循环。yield returnSelect版本将为产生的每个项目调用无操作投影委托。但是,这种差异显着的可能性很小 - 我建议您使用任何使代码对您来说最清晰的方法。

于 2010-04-05T19:56:05.333 回答
3

暴露一个IEnumerable<T>属性:

public IEnumerable<whatevertype> MyHashSet {
    get {
        return this.myHashSet;
    }
}

当然,此代码的用户可以将其强制IEnumerable<T>转换为 aHashSet<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();
}
于 2010-04-05T19:49:28.280 回答
3

添加这样的方法/属性以避免暴露实际容器:

public IEnumerable EnumerateFirst()
{
     foreach( var item in hashSet )
         yield return item;
}
于 2010-04-05T19:50:28.567 回答
3

您还可以使用该Select方法创建一个无法转换回的包装器HashSet<T>

public IEnumerable<int> Values
{
    get { return _values.Select(value => value);
}

这样可以避免重复_values两次,就像您使用.ToArray().

于 2010-04-05T19:55:17.330 回答
0

您还可以提供这样的序列:

public IEnumerable<string> GetHashSetOneValues()
{
    foreach (string value in hashSetOne)
        yield return value;
}

然后可以在 foreach 循环中调用此方法:

foreach (string value in myObject.GetHashSetOneValues())
    DoSomething(value);
于 2010-04-05T19:51:32.233 回答
0

这对聚会来说可能有点太晚了,但今天最简单的方法是使用 Linq。而不是写

public IEnumerable<string> GetValues() 
{
    foreach(var elem in list)
        yield return elem; 
}

你可以写

public IEnumerable<string> GetValues() => list;
于 2018-01-31T13:54:51.553 回答
-1

让您的 getter 将 HashSet 公开为 IEnumerable。

private HashSet<string> _mine;

public IEnumerable<string> Yours
{
    get { return _mine; }
}

如果泛型类型是可变的,那么它仍然可以修改,但不能从 HashSet 中添加或删除任何项目。

于 2010-04-05T19:50:33.577 回答