使用Func<;T、 TResult>;RavenDB的成员

本文关键字:RavenDB gt 成员 TResult Func lt 使用 | 更新日期: 2023-09-27 17:59:17

我有一个类

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中,但这没有帮助。

使用Func<;T、 TResult>;RavenDB的成员

委托不能序列化,因为它们不包含数据,而是包含代码(好吧,委托类型包含一些数据,但在这里没有任何用处)。你想做的事情会被认为是编组。

反序列化后,您的闭包将不再有效:

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配置之间的行为一致。