c# 4.0 -在Esent持久字典中存储对象给出:不支持SetColumn参数错误



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

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

由于许多类实现相同的接口(所有这些都需要缓存),对于泛型方法,我希望在字典中存储IInterface类型的Object。
这样我就可以把对象类型转换为IInterface并使用该对象的内部实现方法等。

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

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

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

有谁知道出去的路吗?提前感谢!!

只支持结构体(以及一些基本的不可变的类,如string)的唯一原因是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之后更新它们将不会自动更新字典中的副本,您需要记住手动更新它。

PersistentDictionary只能存储值结构和非常有限的类子集(string, Uri, IPAddress)。请查看ColumnConverter.cs,在private static bool IsSerializable(Type Type)中查看完整的限制。你会碰到typeinfo.IsValueType()限制。

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

再也

相关内容

  • 没有找到相关文章

最新更新