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

正在检查已实例化的延迟加载属性

  •  4
  • PaulG  · 技术社区  · 14 年前

    在具有惰性加载属性的类中,例如:

    private Collection<int> someInts;
    
    public Collection<int> SomeInts
    {
        get
        {
            if (this.someInts == null) this.someInts = new Collection<int>();
            return this.someInts;
        }
    }
    

    是否也值得拥有如下财产:

    public bool SomeIntsExist
    {
        get { return (this.someInts != null && this.someInts.Count > 0); }
    }
    

    然后使用那个属性……如:

    if (thatClass.SomeIntsExist)
    {
        // do something with thatClass.SomeInts collection
    }
    

    或者这是过早的优化。使用下面这样的工具进行滚动当然更容易,但它将不必要地实例化集合:

    if (thatClass.SomeInts.Count > 0)
    {
        // do something with thatClass.SomeInts collection
    }
    

    编译器是否足够聪明,能够解决这类问题?有更好的方法吗?

    4 回复  |  直到 14 年前
        1
  •  2
  •   Daniel Brückner    14 年前

    即使是懒惰的属性初始化听起来也像是过早的优化。我能想到的只有极少数情况下,延迟创建空集合有助于解决问题(假设您的示例没有过于简单化)。

    但是,当必须延迟集合初始化时,您可能应该(甚至必须)优化 Exists 方法也是如此,因为延迟初始化是一个关键要求。

        2
  •  1
  •   EFrank    14 年前

    编译器不会自动计算出这样的事情。 这意味着,在最后一个案例中

    if (thatClass.SomeInts.Count > 0) 
    { 
        // do something with thatClass.SomeInts collection 
    } 
    

    集合将被实例化。

    所以在我看来,这取决于初始化集合的成本-在简单的情况下,它并不真正昂贵,但是浪费的内存可能会加起来…

        3
  •  1
  •   James    14 年前

    如果您要处理昂贵的数据检索(如数据库查询),我想说拥有这样的属性是值得的。

    但是,您的代码中有一个缺陷。 SomeIntsExist 只有在属性被预先访问的情况下才会给出正确的答案,如果属性被延迟加载,那么可能确实存在整数,但它们还没有被加载。它应该改名为 IsInitialised . 我知道这是一个例子,但可能仍然值得指出:)

        4
  •  0
  •   Jack    14 年前

    如果lazy-loaded类是一个大类,初始化需要一些时间….这样一个布尔型的人会产生感觉。

    如果是一个简单的.NET集合,在我看来,它不会产生影响。