我正在尝试确定使用以下序列化代理启用匿名函数/委托(delegate)/lambda 的序列化可能会导致哪些问题。
// see http://msdn.microsoft.com/msdnmag/issues/02/09/net/#S3
class NonSerializableSurrogate : ISerializationSurrogate
{
public void GetObjectData(object obj, SerializationInfo info, StreamingContext context)
{
foreach (FieldInfo f in obj.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic))
info.AddValue(f.Name, f.GetValue(obj));
}
public object SetObjectData(object obj, SerializationInfo info, StreamingContext context,
ISurrogateSelector selector)
{
foreach (FieldInfo f in obj.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic))
f.SetValue(obj, info.GetValue(f.Name, f.FieldType));
return obj;
}
}
list 1 改编自 Counting Demo
我能想到的主要问题可能是匿名类是一个内部编译器细节,并且不能保证它的结构在 .NET Framework 的修订之间保持不变。根据我对迭代器的类似问题的研究,我相当确定情况就是如此。
背景
我正在研究匿名函数的序列化。我原以为这行不通,但发现在某些情况下确实如此。只要 lambda *不&强制编译器生成匿名类,一切正常。
如果编译器需要生成的类来实现匿名函数,则会抛出 SerializationException。这是因为编译器生成的类未标记为可序列化。
例子
namespace Example
{
[Serializable]
class Other
{
public int Value;
}
[Serializable]
class Program
{
static void Main(string[] args)
{
MemoryStream m = new MemoryStream();
BinaryFormatter f = new BinaryFormatter();
// Example 1
Func<int> succeeds = () => 5;
f.Serialize(m, succeeds);
// Example 2
Other o = new Other();
Func<int> fails = () => o.Value;
f.Serialize(m, fails); // throws SerializationException - Type 'Example.Program+<>c__DisplayClass3' in Assembly 'Example, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' is not marked as serializable.
}
}
list 2
这类似于尝试序列化 iterators 的问题,我在之前的搜索中找到了以下代码(请参阅 countingdemo)使用 list 1 和一个 ISurrogateSelector 我能够成功地序列化和反序列化第二个失败的例子。
目标
我有一个通过网络服务公开的系统。系统有一个复杂但很小的状态(很多对象,而不是每个对象的很多属性)。状态保存在 ASP.NET 缓存中,但也会在缓存过期时序列化为 SQL 中的 BLOB。有些对象需要在达到某些条件时执行任意“事件”。因此它们具有接受 Action/Func 对象的属性。人为的例子:
class Command
{
public Command(Action action, Func<bool> condition);
}
别处
void DoSomethingWithThing(Thing thing)
{
state = Store.GetCurrentState();
Command cmd = new Command(() => thing.Foo(), () => thing.IsReady())
state.Add(cmd);
Store.Save(state);
}
最佳答案
你有没有看到我写的这篇文章作为 CountingDemo 的后续文章:http://dotnet.agilekiwi.com/blog/2007/12/update-on-persistent-iterators.html ?不幸的是,微软已经确认他们可能会(有一天)以一种可能导致问题的方式更改编译器细节。 (例如,f/当您更新到新编译器时,您将无法反序列化在旧(当前)编译器下保存的内容。)
关于c# - 在 C# 中序列化匿名委托(delegate),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/321827/