.net 只读集合不是';我不是只读的。如何创建真正的ReadOnlyCollection?
我知道readonly集合会阻止添加/从列表中删除对象,但为什么它不阻止设置集合中对象的属性呢.net 只读集合不是';我不是只读的。如何创建真正的ReadOnlyCollection?,.net,wcf,readonly-collection,.net,Wcf,Readonly Collection,我知道readonly集合会阻止添加/从列表中删除对象,但为什么它不阻止设置集合中对象的属性呢 System.Collections.ObjectModel.ReadOnlyCollection<PersonPhoneNumber> ReadOnlyPhoneNumbers = new System.Collections.ObjectModel.ReadOnlyCollection<PersonPhoneNumber>(_PhoneNumbers);
System.Collections.ObjectModel.ReadOnlyCollection<PersonPhoneNumber> ReadOnlyPhoneNumbers = new System.Collections.ObjectModel.ReadOnlyCollection<PersonPhoneNumber>(_PhoneNumbers);
ReadOnlyPhoneNumbers[0].Number = "01111111111111";
而不是:
Person.PhoneNumbers.Add(New PersonPhoneNumber{Number= "01111111111111", Type=Mobile});
不能将对象设置为只读。这需要改变类型。如果确实需要提供只读对象列表,则需要为要公开的每个类型创建某种类型的不可变包装器类型(或使类型从一开始就不可变)。当然,这将是一个单独的类型,如果您需要它们进行互操作,这将相当复杂…您不能将对象设置为只读。这需要改变类型。如果确实需要提供只读对象列表,则需要为要公开的每个类型创建某种类型的不可变包装器类型(或使类型从一开始就不可变)。当然,这将是一个单独的类型,如果您需要它们进行互操作,这将是相当复杂的…它如何防止这种情况?你将如何尝试用C#构建这样一个东西?如果支持克隆,它可能会复制从索引器(etc)返回的任何内容,但随后该对象将需要执行克隆。对于刚才给出的代码,您希望发生什么?它应该抛出异常吗?如果是这样,那就是对
PersonPhoneNumber
类本身进行更改
听起来您基本上应该将PersonPhoneNumber
类更改为不可变。如果您需要一种以可变方式构建它的方法,您可以创建一个生成器类型,它知道如何创建PersonPhoneNumber
-例如:
var ppn = new PersonPhoneNumber.Builder { /* set properties here }.Build();
不过,对于相当简单的类型,只需编写适当的构造函数就更容易了。它如何防止这种情况发生?你将如何尝试用C#构建这样一个东西?如果支持克隆,它可能会复制从索引器(etc)返回的任何内容,但随后该对象将需要执行克隆。对于刚才给出的代码,您希望发生什么?它应该抛出异常吗?如果是这样,那就是对PersonPhoneNumber
类本身进行更改
听起来您基本上应该将PersonPhoneNumber
类更改为不可变。如果您需要一种以可变方式构建它的方法,您可以创建一个生成器类型,它知道如何创建PersonPhoneNumber
-例如:
var ppn = new PersonPhoneNumber.Builder { /* set properties here }.Build();
不过,对于相当简单的类型,只需编写适当的构造函数就更容易了。问题在于使对象在进入时成为只读对象-为了使这些对象成为只读对象,您需要将它们包装在某种不允许设置值的代理中 Castle的动态代理可能允许您将对象包装在自己实现的ReadOnlyProxy中。然后,add方法必须在所有内容进入集合时将其包装在ReadOnlyProxy中
不好…问题在于使对象在进入时为只读-为了使这些对象为只读,您需要将它们包装在某种不允许设置值的代理中 Castle的动态代理可能允许您将对象包装在自己实现的ReadOnlyProxy中。然后,add方法必须在所有内容进入集合时将其包装在ReadOnlyProxy中
不好…你想要的不是收藏的问题。集合包含对您的项目的引用,您可以通过访问集合来获取这些项目。
您可以在插入之前尝试克隆对象。这不会阻止它们被更改,但原始对象将被保留。否则,您必须为对象编写一个只读包装器或选择另一种结构。您想要的不是集合的问题。集合包含对您的项目的引用,您可以通过访问集合来获取这些项目。
您可以在插入之前尝试克隆对象。这不会阻止它们被更改,但原始对象将被保留。否则,您必须为对象编写一个只读包装器或选择另一种结构。您可能想看看这篇文章
我认为您想要的是保持phonenumbers列表为真正的私有数据成员,然后通过person对象上的setter和getter为各种类型的电话号码公开对它的访问。如果一个人只能拥有每种类型中的一种,这将很好地工作。。。否则,您必须将其更改为一种方法。像.AddMobile(“011111”)您可能想看看这篇文章 我认为您想要的是保持phonenumbers列表为真正的私有数据成员,然后通过person对象上的setter和getter为各种类型的电话号码公开对它的访问。如果一个人只能拥有每种类型中的一种,这将很好地工作。。。否则,您必须将其更改为一种方法。比如.AddMobile(“011111”)这个怎么样:
PersonPhoneN
ReadOnlyPhoneNumbers[0].Number = "01111111111111";
// Cannot modify the result of an unboxing conversion
PersonPhoneNumber ppn = ReadOnlyPhoneNumbers[0].Number;
ppn.Number = "01111111111111";