【问题标题】:Where is this non-serializable object?这个不可序列化的对象在哪里?
【发布时间】:2011-07-16 06:24:49
【问题描述】:

我正在尝试序列化一个对象并抛出以下 SerializationException:

在程序集“System.Core, Version=4.0.0.0”中键入“System.Linq.Enumerable+d__71`1[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]] , Culture=neutral, PublicKeyToken=b77a5c561934e089' 未标记为可序列化。

我的代码中的这个对象在哪里?我怎么知道?对象图相当大。

【问题讨论】:

  • 它只是用于序列化的堆栈......与无法序列化的对象无关

标签: .net serialization .net-4.0 serializable binary-serialization


【解决方案1】:

尝试使用 Reflector,看看是否可以确定匿名类型 d__71`1 在代码中的使用位置。

【讨论】:

  • 谢谢!我什至没有想过将我的 dll 加载到反射器中。一旦我这样做了,就很容易找到 d__71'1 并分析它的用法。谢谢!
【解决方案2】:

听起来好像您已经存储了调用枚举器方法的结果,而没有将结果转换为列表。

当你有这样的方法时:

public IEnumerable<string> GetMyWidgetNames()
{
    foreach (var x in MyWidgets)
    { 
        yield return x.Name;
    }
}

编译器将其转换为一个嵌套对象,其名称与您所看到的类似(由于嵌入了+,您永远无法自己创建一个名称)

如果您随后将对该对象的引用存储在您尝试序列化的内容中,您将收到 OP 指出的异常。

“修复”是确保您的序列化对象始终将任何 IEnumerable 分配转换为列表。而不是这个

public IEnumerable<string> WidgetNames { get; set; }

你需要写:

public IEnumerable<string> WidgetNames
{
    get { return mWidgetNames; }
    set
    {
        if (value == null)
            mWidgetNames= null
        else mWidgetNames= value.ToList();
    }
}
private List<string> mWidgetNames;

【讨论】:

  • +1, System.Linq.Enumerable... 表示这组数据是从 Linq 查询返回的。虽然它实现了 IEnumerable,但它不是可序列化的。通常需要对这个Linq结果调用ToList()或者ToArray(),然后就可以序列化了。
  • 这很有帮助。我希望让我分开答案。您和@Mark Hurd 的回答帮助我找到了问题所在。实际上,它是一个 IEnumerable,它已被连接并需要展平为一个列表。我掷了一枚硬币来奖励答案。
【解决方案3】:

尝试一次序列化一个对象(单一类型),看看它什么时候爆炸。您可以手动执行此操作,也可以通过反射执行此操作。

【讨论】:

  • 那么 - 为什么要投反对票?这正是我解决问题的方法(我感觉它会起作用)。
猜你喜欢
  • 1970-01-01
  • 2013-03-13
  • 2019-02-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-04
相关资源
最近更新 更多