代码之家  ›  专栏  ›  技术社区  ›  Stéphane

使用Enumerable.Empty<T>()来初始化IEnumerable<T>,与使用new List<T>()相比是否更好?

  •  117
  • Stéphane  · 技术社区  · 15 年前

    假设你有一个班上的人:

    public class Person
    {
       public string Name { get; set;}
       public IEnumerable<Role> Roles {get; set;}
    }
    

    显然,我应该实例化构造函数中的角色。

    public Person()
    {
       Roles = new List<Role>();
    }
    

    但是我发现这个静态方法是在 System.Linq

    IEnumerable<T> Enumerable.Empty<T>();
    

    从…起 MSDN :

    Empty(TResult)() 方法缓存 TResult . 什么时候 它返回的对象被枚举,

    在某些情况下,此方法很有用 用于将空序列传递给 采用 IEnumerable(T) . 它也可以用来 为方法生成中性元素 比如 Union . 请参见示例部分 例如,使用

    那么这样编写构造函数更好吗?你用它吗?为什么?如果不是,为什么不呢?

    public Person()
    {
       Roles = Enumerable.Empty<Role>();
    }
    
    7 回复  |  直到 9 年前
        1
  •  208
  •   Kris van der Mast    4 年前

    Enumerable.Empty 不为每次调用创建对象,从而减少GC的负载。

    如果代码处于低吞吐量位置,那么可以归结为美学方面的考虑。

        2
  •  106
  •   Roman Marusyk S Kotra    7 年前

    Enumerable.Empty<T> 更好是因为它更明确:您的代码清楚地表明了您的意图。它也可能更高效一些,但这只是一个次要优势。

        3
  •  31
  •   Drew Noakes    9 年前

    在性能方面,让我们看看如何 Enumerable.Empty<T> 实现了。

    它回来了 EmptyEnumerable<T>.Instance

    internal class EmptyEnumerable<T>
    {
        public static readonly T[] Instance = new T[0];
    }
    

    也就是说:

    Debug.Assert(ReferenceEquals(Enumerable.Empty<int>(), Enumerable.Empty<int>()));
    
        4
  •  13
  •   Neil Barnwell    10 年前

    Roles 属性,然后通过将其setter设置为私有并将其初始化为构造函数中的新列表来封装它:

    public class Person
    {
        public string Name { get; set; }
        public IList<Role> Roles { get; private set; }
    
        public Person()
        {
            Roles = new List<Role>();
        }
    }
    

    角色 价值 null 避免对象分配。

        5
  •  7
  •   Lee    15 年前

    您的方法存在的问题是无法将任何项添加到集合中-我将使用类似列表的私有结构,然后将这些项公开为可枚举项:

    public class Person
    {
        private IList<Role> _roles;
    
        public Person()
        {
            this._roles = new List<Role>();
        }
    
        public string Name { get; set; }
    
        public void AddRole(Role role)
        {
            //implementation
        }
    
        public IEnumerable<Role> Roles
        {
            get { return this._roles.AsEnumerable(); }
        }
    }
    

        6
  •  7
  •   Hans Passant    15 年前

    将私有列表公开为IEnumerable的典型问题是,类的客户端可以通过强制转换来处理它。该代码将在以下情况下起作用:

      var p = new Person();
      List<Role> roles = p.Roles as List<Role>;
      roles.Add(Role.Admin);
    

    public IEnumerable<Role> Roles {
      get {
        foreach (var role in mRoles)
          yield return role;
      }
    }