.Net中嵌套对象的最佳实践是什么?

时间:2011-08-03 14:05:00

标签: c# .net class object

这个问题与最佳实践有关...请不要将其与过早优化混淆。

我在.Net中注意到,与平面或浅层物体相比,深度物体参考需要相当长的时间来处理。例如:

object1.object2.object3.object4.Property

...效率不高,因为我得出结论,每个对象都必须沿着路径去引用。这与C形成对比,其中Property的内存引用将由编译器计算,而不是在运行时计算。

现在,我们显然不会占用object2 +的所有字段,只是为了速度而将它们展平为object1。编码很笨重,难以管理。但速度差异可能很大。

所以我的问题是,“构建深对象与平坦(ish)对象的最佳做法是什么?”而且,使用结构体是否有任何优势,只需要将多个字段组合在一起,例如:

public struct SizeData
{
    public long Written;
    public long Read;
    public int Size;
}

这两个问题有关。

修改

举例说明:

public class Leaf
{
    public int Property;
}

public class Depth1
{
    public Leaf Leaf;
}

public class Depth2
{
    public Depth1 Depth1;
}

public class Depth3
{
    public Depth2 Depth2;
}

private void button12_Click(object sender, EventArgs e)
{
    Depth3 depth = new Depth3();
    depth.Depth2 = new Depth2();
    depth.Depth2.Depth1 = new Depth1();
    depth.Depth2.Depth1.Leaf = new Leaf();
    Leaf leaf = new Leaf();

    var T1 = Environment.TickCount;

    for (int i = 0; i < 100000000; i++)
    {
        depth.Depth2.Depth1.Leaf.Property++;
    }

    var T2 = Environment.TickCount;

    for (int i = 0; i < 100000000; i++)
    {
        leaf.Property++;
    }

    var T3 = Environment.TickCount;

    MessageBox.Show((T2 - T1).ToString() + Environment.NewLine +
        ((T3 - T2).ToString()));
}

4 个答案:

答案 0 :(得分:3)

在我看来,在你意识到这是一个瓶颈之前,你不应该考虑速度。

类/结构应该纯逻辑地分组:如果你看到某个类是其他类的一部分,那么在更大的类中只需要 并且在更大的类中只有 ,然后你应该把它放在那里,从而避免污染命名空间。如果您看到较小的类在较大的类之外有用,请在外部定义它。那很简单。

总结:将你的班级/结构置于最深的适当水平,但不要更深。

示例:

  1. myCar.RegistrationDate.Year.IsLeap非常有意义,并且优于myCar.IsRegistrationYearLeap
  2. point.Coordinates.Cartesian.X没有多大意义,point.X要好得多。

答案 1 :(得分:3)

术语嵌套类通常用于表示“嵌套类型”。

class Foo
{
   private class FoosHelper { .. }
}

这里最好的做法是谨慎使用它们,而不是私密。


但是你的例子不是关于嵌套类,而是关于嵌套对象

 object1.object2.object3.object4.Property

最佳实践是:首先建立一个逻辑性和内聚性的对象模型。

你对'扁平'的建议似乎是为了牺牲核心架构以进行微小的优化。不是一个好主意。


和(仅略微)相关的结构问题:

  

使用结构体是否有任何优势,只需要将多个字段组合在一起

不,通常不会。在极少数情况下,您需要非常大的小型数组,但通常使用结构只会带来缺点。

答案 2 :(得分:3)

这里唯一的担心恕我直言不是速度,而是依赖。您是否曾尝试重构经常使用此类深层对象嵌套的应用程序?这是一个痛苦的屁股。看看Law of Demeter(或者我说的是德米特指南)。这个想法是代替使用

person.Address.ZipCode

你改用

之类的东西
person.AddressZipCode

以避免依赖于Address对象。它更快吗?也许,如果你正确实施它。但我个人并不在乎,因为加速非常微不足道。我在这里关心的是减少依赖性。

答案 3 :(得分:1)

结构字段将没有单独的内存分配,然后是封闭对象,所以没有差别,如果所有嵌套都是结构,它由编译器计算。

如果嵌套引用类型,则必须取消引用它们,这与C ++没有任何区别。