簡體   English   中英

當使用泛型類型約束時,XmlSerializer拋出InvalidOperationException

[英]XmlSerializer is throwing InvalidOperationException when using the generic type constraint where

當我嘗試運行以下代碼(兩個分離的程序集)時

ClassLibrary.cs

public interface ITest
{
}

Program.cs中

using System;

public class TestClass
{
    public void Test<T>(T x) where T : ITest { }
}

static class Program
{ 
    static void Main(string[] args)         
    {
        new System.Xml.Serialization.XmlSerializer(typeof(TestClass));
    }
}

使用以下命令在Windows 7 64位中編譯:

c:\\ Windows \\ Microsoft.NET \\ Framework \\ v2.0.50727 \\ csc / target:library ClassLibrary.cs

c:\\ Windows \\ Microsoft.NET \\ Framework \\ v2.0.50727 \\ csc /reference:ClassLibrary.dll Program.cs

我得到了這個例外:

System.InvalidOperationException:無法生成臨時類(result = 1)。 錯誤CS0012:類型ITest在未引用的程序集中定義。 您必須添加對程序集ClassLibrary的引用,Version = 0.0.0.0,Culture = neutral,PublicKeyToken = null hinzu。

在System.Xml.Serialization.Compiler.Compile(Assembly parent,String ns,XmlSerializerCompilerParameters xmlParameters,Evidence evidence)
在System.Xml.Serialization.TempAssembly.GenerateAssembly(XmlMapping [] xmlMappings,Type [] types,String defaultNamespace,Evidence evidence,XmlSerializerCompilerParameters參數,Assembly assembly,Hashtable程序集)System.Xml.Serialization.TempAssembly..ctor(XmlMapping [ ] System.Xml.Serialization.XmlSerializer..ctor處的System.Xml.Serialization.XmlSerializer.GenerateTempAssembly(XmlMapping xmlMapping,Type type,String defaultNamespace)中的xmlMappings,Type [] types,String defaultNamespace,String location,Evidence evidence)(Type Program.Main(String [] args)中的type,String defaultNamespace)

TestClass移除where T:ITest或根本不使用泛型(例如使用public void Test(ITest x) )將防止拋出異常,但我需要在我的實際應用程序中使用此構造。

有人理解為什么XmlSerializer無法處理where約束嗎?

我覺得你運氣不好 以下是Microsoft對此問題的回復:

感謝您提交此問題。 不幸的是,我們已經決定不解決它,因為修復的風險超過了它的好處。 當下一次實現此更改的機會出現時,希望未來版本的Windows Communication Foundation中的新序列化技術能夠滿足您的需求。 如果此問題導致嚴重的負面業務影響,請與Microsoft產品支持服務聯系。 我很遺憾我們無法提供更好的解決方案。 請放心,我們認真考慮了這個問題 - 一個不會修復的決定從來都不容易。

這基本上說你應該使用DataContractSerializer而不是XmlSerializer或更改你的對象結構。

實際上,你可能非常接近,甚至不知道。

嘗試在ClassLibrary程序集中定義一個空的幫助器類,並將[Serializable, XmlInclude(SerializationReferenceHelper)]放在public class TestClass之上。

問題是Xml解析器不知道第二個類,因為它位於不同的程序集中,並且僅由代碼中的where約束引用。 是的,微軟可能會寫一些小曲目來查看所有已知的程序集......不確定它們為什么不這樣做。 但是現在這可能會奏效。

ClassLibrary

public class SerializationReferenceHelper { }
public interface ITest { }

程序

[Serializable, XmlInclude(typeof(SerializationReferenceHelper))]
public class TestClass
{
    public void Test<T>(T x) where T : ITest { }
}

static class Program
{ 
    static void Main(string[] args)         
    {
        new System.Xml.Serialization.XmlSerializer(typeof(TestClass));
    }
}

ITest類型在未引用的程序集中定義。 您必須添加對程序集ClassLibrary的引用

你做過這個嗎?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM