Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/264.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类#_C# - Fatal编程技术网

C# 防止修改C类#

C# 防止修改C类#,c#,C#,嗨,我是C#开发环境的新手。有人能帮我吗 修改Coffee类实现,使存储在Coffee中的列表不受原始列表或还原列表修改的影响 使用系统; 使用System.Collections.Generic 公共咖啡 { 私人名单信息; 公共咖啡(列表信息) { this.info=info; } 公共列表还原() { 返回此.info; } } 我不是在寻找答案(填鸭式)而是方向,关于我应该读什么。我是一名PHP开发人员。提前感谢您您可以将其存储为IReadOnlyList Using System;

嗨,我是C#开发环境的新手。有人能帮我吗

修改Coffee类实现,使存储在Coffee中的列表不受原始列表或还原列表修改的影响

使用系统;
使用System.Collections.Generic
公共咖啡
{
私人名单信息;
公共咖啡(列表信息)
{
this.info=info;
}
公共列表还原()
{
返回此.info;
}
}

我不是在寻找答案(填鸭式)而是方向,关于我应该读什么。我是一名PHP开发人员。提前感谢您

您可以将其存储为
IReadOnlyList

Using System;
Using System.Collections.Generic

public class Coffee 
{
    private List<int> info;
    public Coffee(List<int> info)
    {
       this.info = new List<int>(info);
    }
    public List <int> Restore()
    {
       return new List<int>(this.info);
    }
}
公共级咖啡
{
私有IReadOnlyList信息;
公共咖啡(列表信息)
{
this.info=info;//您可以在只读模式下查看原始集合
}
公共列表还原()
{
return info.ToList();//复制原始列表
}
}
更新:很抱歉缺少条件。如果您想存储列表的独立副本,可以使用Colin Mackay的解决方案


附言:没必要这么咄咄逼人,立即否决每个答案。此代码示例对于理解C#for newomer

也很有用。您可以使用LINQ制作列表的副本,方法是在输入(因此您有自己的副本,不受对原始副本的更改影响)和输出(因此调用方获得自己的副本,因此他们的更改不会影响您)的过程中添加
.ToList()

使用系统;
使用System.Collections.Generic
公共咖啡
{
私人名单信息;
公共咖啡(列表信息)
{
this.info=info.ToList();
}
公共列表还原()
{
返回此.info.ToList();
}
}

创建您的
列表的新实例

Using System;
Using System.Collections.Generic

public class Coffee 
{
    private List<int> info;
    public Coffee(List<int> info)
    {
       this.info = new List<int>(info);
    }
    public List <int> Restore()
    {
       return new List<int>(this.info);
    }
}
使用系统;
使用System.Collections.Generic
公共咖啡
{
私人名单信息;
公共咖啡(列表信息)
{
this.info=新列表(info);
}
公共列表还原()
{
返回新列表(this.info);
}
}

如果您使用的是现代.NET版本,一种方法是返回一个
ReadOnlyCollection
对象——这是一个围绕集合的包装器,如果您试图修改它,它将抛出异常
List.AsReadOnly()
创建此包装。但它不是静态类型安全的——它不会阻止您编写糟糕的代码。它绝对不会阻止某人修改元素本身:
roList[3].name=“foo”

另一种方法是复制列表。这是安全的,适用于较旧的.NET版本,但有开销。插入元素后,将修改新列表。因为它不是深度副本,所以可以像前面的示例一样更改元素

第三种可能是在返回对象之前将对象强制转换为
IEnumerable
,因为它根本没有列表访问器API。您仍然可以使用
foreach
在元素上循环。这实际上会阻止您编写非法代码,除非对象被回滚到
列表
。这将使使用列表的代码速度稍慢,编写起来也不太方便,因为API比
list
更受限制


这些方法都不使用深度复制,这是防止对象修改的唯一真正安全的方法。由于许多类型的对象都不可能进行深度复制,因此这不是一个可行的解决方案。

深入研究复制-深度和浅层复制(使用ints,您需要的只是浅层但仍然)请注意,这不是一个好问题,因为即使您环顾四周,这仍然是一个“做我的功课”/“给我一些参考”问题。。。以后要避免这些问题。它们通常是关闭和否决的;)你的担心是不必要的,因为
int
是一种值类型,无论如何都会被“深度”复制。这同样适用于所有其他值类型。但是,如果您有一个类(引用类型)的一些实例的列表,则需要一个adeep副本。在本例中,这个问题有数千个重复项,仅“deep clone c#”的ggole@HimBromBeere:请注意,包含对可变类型的引用的值类型仍需要进行深度克隆。@HimBromBeere-半正确。通过返回对该列表项的引用,可以将其添加到列表中。列表的创建者在将列表传递给coffee类后仍然可以修改列表,这是条件之一。这只起作用,因为我们有一个int的列表,然而,正如吉拉德·格林尼所说,即使不调用
ToList
,它也能工作。我无法完全解析你的句子。为什么它是一个重要的列表?如果它是一个
列表,OP说他们不想修改列表,不是说他们不想修改列表中的对象。一份浅薄的副本就足以满足OP的要求。在任何情况下,不可变对象(如int)都不需要深度复制,因为它是不可变的并且不能被改变。问题是修改列表,而不是它包含的对象,所以我会认为这是一个有效的答案。关于需要深度克隆的说法似乎对这个问题理解得太多了。为什么要下载这个答案?它符合OP要求,构造函数中传递的列表更改和还原方法返回的列表更改不会影响私有
info
list。要求是:这样存储在咖啡中的列表就不会受到对原始列表或恢复列表的修改的影响,看起来我们不会得到关于向下投票的问题的答案。
using System;
using System.Collections.Generic

public class Coffee 
{
    private List<int> info;
    public Coffee(List<int> info)
    {
      this.info = info.ToList();
    }
    public List <int> Restore()
    {
      return this.info.ToList();
    }
}
Using System;
Using System.Collections.Generic

public class Coffee 
{
    private List<int> info;
    public Coffee(List<int> info)
    {
       this.info = new List<int>(info);
    }
    public List <int> Restore()
    {
       return new List<int>(this.info);
    }
}