Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/273.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 不变性与集合_C#_Collections_Immutability - Fatal编程技术网

C# 不变性与集合

C# 不变性与集合,c#,collections,immutability,C#,Collections,Immutability,你好,我有一个问题,这是不变性的坏方法吗?如果是,为什么?我的意思是,如果向集合添加或从集合中删除项目,则不会更改对象的状态,它仍然有一个相同的集合。当您对该集合进行评级时,它的数量和是否包含项目并不重要。当你要求它,你会得到所有不同的参考,你不能修改。如果这是一种糟糕的做法,那么使用不可变集合的优点在哪里 谢谢大家! using System; using System.Collections.Generic; class Test { private readonly List&l

你好,我有一个问题,这是不变性的坏方法吗?如果是,为什么?我的意思是,如果向集合添加或从集合中删除项目,则不会更改对象的状态,它仍然有一个相同的集合。当您对该集合进行评级时,它的数量和是否包含项目并不重要。当你要求它,你会得到所有不同的参考,你不能修改。如果这是一种糟糕的做法,那么使用不可变集合的优点在哪里

谢谢大家!

using System;
using System.Collections.Generic;

class Test
{
    private readonly List<object> items;

    public object[] Items { get { return this.items.ToArray(); } }

    public Test(params object[] items)
    {
        this.items = new List<object>();
        this.items.AddRange(items);
    }

    public void AddItem(object item)
    {
        this.items.Add(item);
    }
}
这是不变性的坏方法吗

是的

如果某个内容是不可变的,则其构造函数返回后其状态无法更改

查看AddItem方法正在执行的操作:

public void AddItem(object item)
{
    this.items.Add(item);
}
items是类的字段之一,您正在向其中添加内容。这是构造后更改状态的示例

等一下,外部代码只能通过访问属性项来访问项,这将在每次客户端代码无法更改时创建一个新引用!你可能会说

您这样说是基于这样一个假设,即客户端代码将只传递Test.Items,这实际上在发生变化时不会影响测试对象的状态。但是,如果有人写了这样的东西怎么办:

public static void Foo(Test test) {
    test.AddItem(new object());
}
Test t = new Test("Hello");
var itemsBefore = t.Items;
Foo(t);
var itemsAfter = t.Items;
这个方法显然是在改变传入的参数,不是吗?您可以这样做:

public static void Foo(Test test) {
    test.AddItem(new object());
}
Test t = new Test("Hello");
var itemsBefore = t.Items;
Foo(t);
var itemsAfter = t.Items;
如果测试是不可变的,则itemsBefore和itemsAfter应该具有相同的项。但在现实中,它们并不相同。这意味着测试是可变的


如果要使其不可变,则应使AddItem返回一个新的测试对象,并在其中添加新项。

如果要从列表中添加/删除项,根据定义,它不是不可变列表。I。。。我甚至不知道该对这个说些什么。@maccettura显然是你想出来了。@Servy技术上是正确的-最好的一种correct@moozy.wu不变性和只读性不是一回事。除此之外,这段代码没有太多意义,它当然不是一成不变的。事实上,你可以添加到你的名单应该立即告诉你。如果您有一个接受列表的公共属性,并且它替换了您的私有字段项,那么这将是不可变的。您不能更改项目,只能使其成为一个全新的事物。请看System.String以获取这方面的示例。你永远不会修改字符串,你只会创建一个新的字符串YeYeYe我理解这一部分。我想我可能在收集错误的方式,而不是不可变本身,谢谢:@ MOZZY。如果你认为我的答案回答你的问题,请考虑通过点击那个标记接受它!