代码之家  ›  专栏  ›  技术社区  ›  DGH

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

  •  2
  • DGH  · 技术社区  · 14 年前

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

    7 回复  |  直到 14 年前
        1
  •  3
  •   strager    14 年前

    暴露 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
  •  6
  •   Jon Skeet    14 年前

    假设您使用的是.NET3.5,那么除了自己编写生成代码之外,还有一种方法可以调用LINQ方法。例如:

    public IEnumerable<string> HashSet
    {
        get { return privateMember.Select(x => x); }
    }
    

    public IEnumerable<string> HashSet
    {
        get { return privateMember.Skip(0); }
    }
    

    Skip(0) 可能是最有效的,因为在初始的“跳过0值”循环之后,它可能只是 foreach / yield return 循环显示在其他答案中。这个 Select 版本将为生成的每个项调用no op projection委托。然而,这种差异显著的可能性在天文上是很小的,我建议您使用使代码最清晰的东西。

        3
  •  3
  •   Morten Mertner    14 年前

    public IEnumerable EnumerateFirst()
    {
         foreach( var item in hashSet )
             yield return item;
    }
    
        4
  •  3
  •   Bryan Watts    14 年前

    您也可以使用 Select 方法创建一个包装器,但无法将其强制转换回 HashSet<T> :

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

    _values 两次,就像你对我一样 .ToArray()

        5
  •  0
  •   Jeffrey L Whitledge    14 年前

    您还可以提供如下序列:

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

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

    foreach (string value in myObject.GetHashSetOneValues())
        DoSomething(value);
    
        6
  •  0
  •   Alrekr    6 年前

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

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

    你可以写

    public IEnumerable<string> GetValues() => list;
    
        7
  •  -1
  •   Michael Meadows    14 年前

    使getter将哈希集公开为IEnumerable。

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

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