我有一个类
class Test
{
public string SomeValue { get; set; }
public Func<int, string> DoStuff { get; set; }
}
然后我像下面的一样实例化
Test t = new Test();
t.SomeValue = "Your number: ";
t.DoStuff = (n) => { return t.SomeValue + n.ToString(); };
之后,我尝试将t
存储在RavenDB 中
RavenSession.Store(t);
RavenSession.SaveChanges(); // This fails
如以上评论中所述,RavenSession.SaveChanges()
失败,并显示消息
Raven.Imports.Newtonsoft.Json.JsonSerializationException:Self检测到类型为的属性"extension"的引用循环'ExampleProject.Test.Path'DoStuff.target0'.
然而,当我使用Json.NET序列化对象时,如以下
string s = Newtonsoft.Json.JsonConvert.SerializeObject(t);
对象被序列化得很好,没有任何错误。
我必须以不同的方式配置RavenDB会话吗?(我使用所有默认值)
我已经尝试将[JsonObject(IsReference = true)]
添加到类Test
中,但这没有帮助。
委托不能序列化,因为它们不包含数据,而是包含代码(好吧,委托类型包含一些数据,但在这里没有任何用处)。你想做的事情会被认为是编组。
反序列化后,您的闭包将不再有效:
Test t = new Test();
t.SomeValue = "Your number: ";
t.DoStuff = (n) => { return t.SomeValue + n.ToString(); };
var deserialized = JsonConvert.Deserialize<Test>(JsonConvert.Serialize(t));
var yourNumber = deserialized.DoStuff(1); // What the heck happens here??
然而,我甚至无法让Func使用Json.Net进行序列化,因为它没有正确实现ISerializable:
class FuncTest
{
public Func<int, string> DoStuff { get; set; }
public string Value { get; set; }
}
[Test]
public void Test_Func()
{
var test = new FuncTest();
test.DoStuff = (num) => num.ToString();
var deserialized = JsonConvert.DeserializeObject<FuncTest>(JsonConvert.SerializeObject(test));
deserialized.Value = deserialized.DoStuff(5);
Assert.That(deserialized.Value == "5");
}
Newtonsoft.Json.JsonSerializationException:ISerializable类型"System.Func `2[System.Int32,System.String]"没有有效的构造函数。若要正确实现ISerializable,应存在接受SerializationInfo和StreamingContext参数的构造函数。
在任何情况下,您都不应该期望在反序列化之后保留委托的值。我会在委托上使用[JsonIgnore]
属性,以确保Json.Net配置之间的行为一致。