繁体   English   中英

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

[英](C#) iterate over read-only private collection member

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

假设您使用的是.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 / yield return循环。 Select版本将为每个产生的项目调用no-op投影委托。 这种差异很大的可能性在天文数字上很小,但是 - 我建议你选择使代码最清晰的东西。

公开IEnumerable<T>属性:

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

当然,此代码的用户可以将IEnumerable<T> HashSet<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();
}

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

public IEnumerable EnumerateFirst()
{
     foreach( var item in hashSet )
         yield return item;
}

您还可以使用Select方法创建一个包装器,而不是将其HashSet<T>HashSet<T>

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

这样可以避免迭代_values两次,就像使用.ToArray() ,但是将实现保持在一条简洁的行中。

您还可以提供如下序列:

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

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

foreach (string value in myObject.GetHashSetOneValues())
    DoSomething(value);

这可能对派对来说太晚了,但今天最简单的方法就是使用Linq。 而不是写作

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

你可以写

public IEnumerable<string> GetValues() => list;

让你的getter将HashSet公开为IEnumerable。

private HashSet<string> _mine;

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM