C#:将复杂的对象列表传递给另一个类会占用大量内存

时间:2016-09-01 10:36:27

标签: c# memory command-pattern

这个问题不直接针对移动应用程序。我需要为撤消和重做功能创建一个与Command Pattern相关的结构。我将拥有的命令是AddStrokeCommand,RemoveStrokeCommand和ClearAllCommand。每个都可以撤消。

我需要一个接口说ICommand与Execute和UnExecute。

我的代码示例:

        public class AddStrokeCommand : ICommand
    {
        public event EventHandler CanExecuteChanged;
        public ObservableCollection <Stroke> Strokes { get; set;}  

        public AddStrokeCommand (ObservableCollection<Stroke> strokes) {
            Strokes = strokes;
        }

        public bool CanExecute(object parameter)
        {
            throw new NotImplementedException();
        }

        public void Execute(object parameter)
        {
            Strokes.Add( (Stroke) parameter);
        }

        public void UnExecute()
        {
            Strokes.Remove( (Stroke) parameter); 
        }
    }

应用程序本身显示了许多可以注释的页面,因此可能在每个页面上绘制了大量的Strokes。如果我将笔画传递给每个命令对象,它会使用大量内存吗?会有更好的选择吗?

3 个答案:

答案 0 :(得分:3)

通常,对象的实例是通过引用传递的,这意味着它们不会导致复制内存,只传递指向内存的指针。

这样做的好处是它不会占用内存,也不会影响性能。

缺点(但也可能是一个优点),如果更改传递的项目,即使在返回调用函数之后,更改仍将保留(因为只有一个数据实例)。

在这里你可以看到更多细节: https://msdn.microsoft.com/en-us/library/4d43ts61%28v=vs.90%29.aspx

答案 1 :(得分:1)

传递CLASS不会占用任何重要的内存 - 通常只使用几个字节来保存内存地址。它基本上传递一个整数,它是虚拟内存中对象的位置。 (谷歌周围的&#39;传递引用语义&#39;)

STRUCT是另一回事。每次将结构传递给函数或分配给另一个变量时,都会复制该结构,因此您可能会发现自己在此处进行复制。请参阅&#39;按值传递语义&#39;更多。

答案 2 :(得分:1)

如果您有以下代码:

var myObject = new SomeVeryBigAndComplexObject();

您将创建一个新的非常大的对象并将其存储在先前由运行时分配的某个内存中。存储在myObject中的,如果SomeVeryBigAndComplexObject引用类型(a class),则不是对象本身,只是该对象所在位置的内存地址。

因此,当您执行以下任何操作时:

var obj = myObject;
Foo(myObject);

void Foo(SomeVeryAndComplexObject obj) { ... }

您真正在做的只是将参考myObj中存储的复制到obj,而不是对象本身。这非常便宜,你根本不用担心它。

请记住,对于引用类型,所有这些都是正确的。如果对象是值类型(a struct),那么对象本身将被复制,因为对象本身是变量myObject的值;这就是为什么结构应该总是小对象的原因之一。