代码之家  ›  专栏  ›  技术社区  ›  Jeffrey Kern

对象库-访问索引值还是对象本身?(例如,可能是深度还是浅拷贝?)

  •  0
  • Jeffrey Kern  · 技术社区  · 15 年前

    我一直对.NET如何复制引用感到困惑/不确定。 假设我有一个gdi+的位图对象。

    dim foo as new bitmap("c:\foo.bmp")
    

    “foo”保存位图对象。 现在假设我这样做。

    dim bar as bitmap = foo
    

    这是浅拷贝还是深拷贝?如果我将foo设置为Nothing,那么bar是否也突然引用了“Nothing”?或者bar是否也包含位图的副本,为了从内存中完全删除位图,我需要将“foo”和“bar”都设置为Nothing?

    我需要在内存中保存一个位图库,对我来说,将每个创建的对象中的每个位图的引用存储为一个变量,而不是用索引对其进行编码,并且每次需要时都必须引用该库(如“bitmap library.singleton.getbitmap(id)”)。

    简言之,我可以这样做吗:

    struct graphic object
        dim myBitmap as bitmap
    
        sub draw(g as graphics)
              g.drawimage(myBitmap)
        end sub
    

    而不是这个:

    struct graphic object
        dim myBitmapIndex as integer
    
        sub draw(g as graphics)
              g.drawimage(bitmaplibrary.getImage(myBitmapIndex))
        end sub
    
    1 回复  |  直到 15 年前
        1
  •  0
  •   codekaizen    15 年前

    一般来说,对对象的引用只是复制引用。对于从System.ValueType继承并复制它的类型,这不是真的。

    例如:

    Dim foo as new Bitmap("C:\foo.bmp")
    Dim bar as Bitmap = foo
    
    ''//Now close foo
    foo.Dispose()
    ''//Access to bar fails, since the object it was pointing to was the same as foo
    Console.WriteLine(bar.PixelHeight)
    

    对于System.ValueType后代:

    Dim p1 as new Point(1, 2)
    Dim p2 as Point = p1
    
    p1.Offset(1, 0)
    
    Console.WriteLine(p1)  ''//Prints (2, 2)
    Console.WriteLine(p2)  ''//Prints (1, 2)
    

    如果我设置 foo 什么都没有,那么我只是把参考点指向了其他的东西(什么都没有),并且没有改变对象 bar 参考文献。

    如果要存储对象列表,那么将它们存储在列表结构中似乎是最谨慎的做法。但是,如果您知道您将只拥有一个固定的、数量很少的对象,那么将引用作为类的字段保存可能是一个可行的选项。在您的案例中,您通过方法抽象访问 getImage 这是一个很好的设计选择,因为这样你的类的用户就不必费心了解你跟踪引用的策略,并且你应该能够在不破坏依赖于类的对象的情况下根据需要更改它。