2

我正在尝试保存一个实现接口的对象,比如 IInterface。

private PersistentDictionary<string, IInterface> Object = new PersistentDictionary<string, IInterface>(Environment.CurrentDirectory + @"\Object");

由于许多类实现了相同的接口(所有这些都需要缓存),因此对于通用方法,我想将 IInterface 类型的 Object 存储在字典中。
这样我就可以在任何地方拉出该对象类型,将其转换为 IInterface 并使用该对象的内部方法实现等。

但是,一旦初始化 Esent 缓存,它就会引发此错误: SetColumn 参数名称
不支持:TColumn 实际值为 IInterface。

我试图不使用XmlSerializer做同样的事情,但无法反序列化接口类型。此外,[Serializable]属性不能在接口之上使用,所以我被卡住了。

我还尝试将接口的所有实现(类)[Serializable]作为垂死的尝试,但没有用。

有人知道出路吗?提前致谢 !!!

4

2 回答 2

5

仅支持结构(以及一些基本的不可变类,例如字符串)的唯一原因是它PersistentDictionary旨在替代Dictionary,SortedDictionary和其他类似的类。

假设我有以下代码:

class MyClass
{
    int val;
}

.
.
.

var dict = new Dictionary<int,MyClass>();
var x = new MyClass();
x.val = 1;
dict.Add(0,x);
x.val = 2;
var y = dict[0];
Console.WriteLine(y.val);

在这种情况下,输出为 2。但如果我使用PersistentDictionary代替常规输出,则输出将为 1。该类是使用值 1 创建的,然后在将其添加到字典后进行更改。由于类是引用类型,当我们从字典中检索项目时,我们也将拥有更改后的数据。

由于PersistentDictionary将数据写入磁盘,因此它不能真正以这种方式处理引用类型。对其进行序列化并将其写入磁盘本质上与将对象视为值类型(制作完整副本)相同。

因为它打算用来代替标准字典,而且它不能以完全透明的方式处理引用类型,所以开发人员选择只支持结构,因为结构已经是值类型。

但是,如果您意识到这个限制并承诺要小心不要落入这个陷阱,那么您可以让它很容易地序列化类。只需下载源代码并编译您自己的 EsentCollections 库版本。您需要对其进行的唯一更改是更改此行:

if (!(type.IsValueType && type.IsSerializable))

对此:

if (!type.IsSerializable)

这也将允许将类写入PersistentDictionary,前提是它是可序列化的,并且它的成员也是可序列化的。一个巨大的好处是它还允许您以这种方式在其中存储数组。您需要记住的是它不是真正的字典,因此当您向其中写入对象时,它将存储该对象的副本。因此,在将对象的任何成员添加到之后更新它们PersistentDictionary也不会自动更新字典中的副本,您需要记住手动更新它。

于 2015-02-20T16:25:34.623 回答
1

PersistentDictionary 只能存储值结构和非常有限的类子集(字符串、Uri、IPAddress)。查看 ColumnConverter.cs,在 private static bool IsSerializable(Type type) 中了解完整限制。你会遇到 typeinfo.IsValueType() 限制。

顺便说一句,您还可以尝试在http://managedesent.codeplex.com/discussions上发布有关 PersistentDictionary 的问题。

-马丁

于 2013-01-10T08:01:55.070 回答