创建完整的只读对象列表的最佳方法
Posted
技术标签:
【中文标题】创建完整的只读对象列表的最佳方法【英文标题】:Best way to create a complete readOnly list of object 【发布时间】:2015-05-14 08:43:34 【问题描述】:我正在使用C# 4.0
、Asp.Net
。我对在我创建的自定义缓存中正确构建 readonly
结构有疑问。
详情(摘要):
我的 CacheManager 类(单例)使用现有 MemoryCache
类的实例作为参数,并包含一些有用的方法来处理我的自定义缓存中的对象生命周期等补充内容。
那个经理处理一个简单的CachableObject
,它接受三个变量:
object
DateTime
int
(持续时间)
总之,我的自定义缓存管理器在有限的时间内存储objects
,以保护我的数据库免受频繁的大查询。
最近,我尝试:
从缓存中取回一个对象(即:存储在密钥-MyList
下)
将其转换回复杂对象列表
翻译了每个复杂对象的一些属性的内容
再次将新翻译的对象列表存储在缓存中,(在另一个键 -MyTranslatedList
下)
问题: 在我的测试过程中,在我看来,存储在缓存中的两个列表(原始列表和翻译列表)都引用了相同的底层对象。因此,一旦翻译,这些对象实际上在两个列表中都被翻译了。 由于每个列表都只有对对象的引用,这是一种完全正常的行为,也是我犯的一个愚蠢的错误。
问题: 正如你现在很容易猜到的那样,我想保护我自己和我的单例的其他用户,以免出现这种错误。
我想插入(或存储或获取)任何类型的对象(或复杂对象的列表),因此任何通过缓存获取它们的人都无法更改它们。我希望我的缓存中的数据是只读的(并且 deeply 只读)以避免出现这种问题。我希望任何人在开始使用缓存中存储的数据之前拥有创建一个深层副本(或者更好的是,获得一个)。
到目前为止我尝试了什么:
我试图将object
设为只读。它没有按预期工作。
由于我经常存储复杂对象的列表,因此我发现了返回 IReadOnlyCollection
的 AsReadOnly 方法,但这会阻止我更改列表(添加、删除),但它并不能保护那些在列表中。
我希望我的解释有点可以理解 :) 有没有一种巧妙的方法来处理这种情况?
【问题讨论】:
不,如果某人引用了某个对象,则无法阻止他更改该对象。如果实在不想更改对象,可以将它们设为ICloneable
或为它们提供只读接口。
你可以使用Immutable collections
@Sameer 谢谢你的回答 Sameer。到目前为止,据我了解,不可变集合提供了对不会更改的列表的线程安全访问。它不保证列表中的元素不会改变...你知道我的意思吗?
@Spo1ler 感谢您的回答 Spo1ler。嗯,问题在于,由于我将随机对象放入缓存中,因此我无法更改所有对象以使其可 ICloneable。有意义吗?
【参考方案1】:
我会创建一个属性为只读的类:
class ReadonlyClass
private string p1;
private int p2;
public ReadonlyClass(string property1, int property2)
p1 = property1;
p2 = property2;
public string Property1
get return p1;
public int Property2
get return p2;
如果属性是对象/其他类,您应该实现一个返回对象副本的克隆函数。上述类的克隆函数如下所示:
public ReadonlyClass clone()
return new ReadonlyClass(p1, p2);
最好的问候 汉斯·米林...
【讨论】:
您好汉斯,谢谢您的回答。问题是,我的缓存中可以有任何类型的对象。它还包括在我的源代码之外构建的对象,例如从查询返回的实体框架对象。以上是关于创建完整的只读对象列表的最佳方法的主要内容,如果未能解决你的问题,请参考以下文章