3

考虑以下。您有一个要使用 XmlSerializer 序列化的类,该类具有公共泛型方法,该方法具有类型约束,其中类型位于不同的程序集中:

using BarStuff;

namespace FooStuff {
  public class Foo {
    ...
    public T GetBar<TBar, T>( string key ) where TBar : Bar<T> {
      ...
    }
  }
}

您不会期望 XmlSerializer 甚至会关注方法,而且通常不会。以下两者都可以正常工作:

//private, serializer doesn't care about it
private T GetBar<TBar, T>( string key ) where TBar : Bar<T> {
  ...
}

//no generic type constraint, serializer also doesn't care about it
public Bar GetBar( string key ) {
  ...
}   

此外,如果类型 Bar 与 Foo 在同一个程序集中,那么序列化程序也会非常高兴。

当您执行第一个示例时,如果 Bar 是在单独的程序集中定义的,您将收到一个运行时异常,指出您需要添加对包含 Bar 的程序集的引用,即使您的项目引用中已经有了该程序集。您可以使用 XmlInclude 解决此问题:

[XmlInclude(typeof(Bar))]
public class Foo {
  public T GetBar<TBar, T>( string key ) where TBar : Bar<T> {
    ...
  }
}

但是,如果 Bar 不可序列化,并且没有理由这样做,那么您现在将在第一次遇到无法序列化的内容时获得运行时异常,例如返回接口作为其类型的公共属性,没有无参数构造函数的类等!

相关但不详细:XmlSerializer is throwing InvalidOperationException when using the generic type constraint where

另外:微软对这个问题的看法

4

1 回答 1

3

一些解决方法:

  • 使用不同的序列化器,例如DataContractSerializer
  • 确保类型在同一个程序集中,这样就不需要 XmlInclude (yuck)
  • 更改 Bar 以使其可序列化(糟糕)
  • 避免使用此类方法,即仅序列化 DTO 类型对象并在其他地方具有任何此类功能
  • 这是鬼鬼祟祟的......包括一个可在与您的类型 Bar 相同的程序集中序列化的虚拟类,然后 XmlInclude 代替,这将使序列化程序高兴,即:

例子:

namespace BarStuff {
  //the serializer is perfectly happy with me
  public class DummyBar{}

  //the serializer doesn't like me
  public class Bar{
  ...
  }

  ...
}

using BarStuff;
namespace FooStuff {
  [XmlInclude(typeof(DummyBar))]
  public class Foo {
    public T GetBar<TBar, T>( string key ) where TBar : Bar<T> {
      ...
    }
  }
于 2010-09-15T02:54:44.543 回答