如果在另一个程序集中键入并且要求该类型是可序列的,则XmlSerializer需要XmlInclude用于具有泛型约束的公共方法!

时间:2010-09-15 02:47:36

标签: c# .net generics constraints xmlserializer

请考虑以下事项。您有一个要使用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不可序列化,并且没有理由它,那么现在它将在第一次遇到它无法序列化的东西时获得运行时异常,例如返回接口的公共属性type,没有无参数构造函数的类等。

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

另外:Microsoft's take on the problem

1 个答案:

答案 0 :(得分:2)

一些解决方法:

  • 使用其他序列化程序,例如DataContractSerializer
  • 确保类型在同一个程序集中,以便不需要XmlInclude(yuck)
  • 更改栏以使其可序列化(yuck)
  • 避免使用此类方法,即仅通过序列化DTO类型对象并在其他地方具有任何此类功能
  • 这是偷偷摸摸和hackish ...包括一个虚拟类, 可在与类型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> {
      ...
    }
  }