(C#)迭代只读私有集合成员

时间:2010-04-05 19:46:38

标签: c# iteration hashset private-members

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

7 个答案:

答案 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中添加或删除任何项目。