访问 class 的重对象成员的正确方法

The proper way of accessing heavy object members of class

我有一个 class 这样的:

class BuildingFloor
{
    // The list of building rooms;
    // Room is "heavy" object with many-many fields
    List< Room > m_rooms;

    // The list of all apertures on the floor
    List< Aperture > m_apertures;
    ...
    List< Room > Rooms
    {
        get { return m_rooms; }
    }

    List< Aperture > Doors
    {
        get{ return GetAperturesOfType( 2 ); }
    }
    public List< Aperture > Exits
    {
        get{ return GetAperturesOfType( 3 ); }
    }
    ...
    List< Aperture > GetAperturesOfType( int type )
    {
        var apertures = new List<ApertureWrapper>();
        foreach ( var aper in m_apertures )
        {
            if ( ( aper.Type == type ) )
            {
                apertures.Add( aper );
            }
        }
        return apertures;
    }
}

我的问题是:
1) 当客户端代码访问Rooms 属性;
时,是否会复制m_rooms 2) 在 Doors 属性 调用中将构造多少次 List<> 对象。

那么,我可以更改此代码以使其更快吗?
我需要在
这样的代码中大量使用这些属性 foreach( var door in m_floor.Doors) { ... }
注意:Profiler 说 Exits 属性 花费了大量时间。证明:

Will m_rooms be copied when client code will access Rooms property

是的。但是 m_rooms 的值只是一个引用——它本身并不是一个 List<Room> 对象。您可能想阅读我关于 reference types and value types.

的文章

How many times List<> object will be constructed on the Doors property call.

  1. 调用了一次GetAperturesOfType,构造了一个新的List<ApertureWrapper>

您的 属性 可以更简单地实现为:

return m_apertures.Where(x => x.Type == 2).ToList();

(听起来您可能也想要一个 ApertureType 枚举...)

另请注意,如果您只是需要遍历门,您可以只使用:

return m_apertures.Where(x => x.Type == 2);

并完全避免创建 List<>。请注意,这在其他方面会有不同的语义...

Profiler says Doors property spent significant amount of time.

好吧,您需要查看实际有多少个孔,有多少个门,以及您调用 Doors 属性 的频率。仅从您向我们展示的内容,我们无法真正判断总体上什么是重要的。性能工作通常是上下文相关的。

编辑:现在我们已经看到了调用代码,如果您使用局部变量会更好:

var exits = m_building.CurrentFloor.Exits;
for (int i = 0; i < exits.Count; i++)
{
    // Use exits[i] within here
    // Set exitId to i + 1 if you find the exit.
    // (Or ideally, change everything to be 0-based...)
}

否则,您将为循环的每次迭代创建一个新列表。