簡體   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