2017-05-13 21 views
1

ユーザーは、XMLでEnum型を指定できるアプリケーションを設計しようとしています。そのアプリケーションから、特定のメソッドを実行しますその列挙型(辞書を使用して)。私はXMLのEnum部分にハングアップしています。異なるEnum型のクラスを直列化するEnum型

public class TESTCLASS 
{ 
    private Enum _MethodType; 

    [XmlElement(Order = 1, ElementName = "MethodType")] 
    public Enum MethodType 
    { 
     get { return _MethodType; } 
     set { _MethodType = value; } 
    } 
    public TESTCLASS() { } 

    public TESTCLASS(Enummies.BigMethods bigM) 
    { 
     MethodType = bigM; 
    } 
    public TESTCLASS(Enummies.SmallMethods smallM) 
    { 
     MethodType = smallM; 
    } 
} 

public class Enummies 
{ 
    public enum BigMethods { BIG_ONE, BIG_TWO, BIG_THREE } 
    public enum SmallMethods { SMALL_ONE, SMALL_TWO, SMALL_THREE } 
} 

そして例外でTestClassを結果をシリアル化しようとしている:

string p = "C:\\testclass.xml"; 
TESTCLASS testclass = new TESTCLASS(Enummies.BigMethods.BIG_ONE); 
TestSerializer<TESTCLASS>.Serialize(p, testclass); 

System.InvalidOperationException: The type Enummies+BigMethods may not be used in this context. 

私のシリアル化の方法は、次のようになります。

public class TestSerializer<T> where T: class 
{ 
    public static void Serialize(string path, T type) 
    { 
     var serializer = new XmlSerializer(type.GetType()); 
     using (var writer = new FileStream(path, FileMode.Create)) 
     { 
      serializer.Serialize(writer, type); 
     } 
    } 

    public static T Deserialize(string path) 
    { 
     T type; 
     var serializer = new XmlSerializer(typeof(T)); 
     using (var reader = XmlReader.Create(path)) 
     { 
      type = serializer.Deserialize(reader) as T; 
     } 
     return type; 
    } 
} 

私はMethodTypeでいくつかのチェック/鋳造を含む試してみましたゲッターが、これは同じエラーになります。

public Enum MethodType 
    { 
     get 
     { 
      if (_MethodType is Enummies.BigMethods) return (Enummies.BigMethods)_MethodType; 
      if (_MethodType is Enummies.SmallMethods) return (Enummies.SmallMethods)_MethodType; 
      throw new Exception("UNKNOWN ENUMMIES TYPE"); 
     } 
     set { _MethodType = value; } 
    } 
+0

どのような列挙型が存在するのか、事前に知っていますか? – dbc

答えて

1

私はXmlSerializerであなたのクラスをシリアル化しようとすると、私が得る最も内側の例外がある:

Message="System.Enum is an unsupported type. Please use [XmlIgnore] attribute to exclude members of this type from serialization graph." 

これは自明である:あなたが、型が抽象型System.Enumあるメンバーをシリアル化することはできません。

System.Objectのメンバをシリアル化することができます。発生する可能性のあるすべての型の値が、[XmlInclude(typeof(T))]を使用して静的に宣言されている場合に限ります。

<TESTCLASS xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <MethodType xsi:type="BigMethods">BIG_THREE</MethodType> 
</TESTCLASS> 

それとも

<?xml version="1.0" encoding="utf-16"?> 
<TESTCLASS xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <MethodType xsi:type="SmallMethods">SMALL_TWO</MethodType> 
</TESTCLASS> 

お知らせxsi:type属性を次のように

// Include all possible types of Enum that might be serialized 
[XmlInclude(typeof(Enummies.BigMethods))] 
[XmlInclude(typeof(Enummies.SmallMethods))] 
public class TESTCLASS 
{ 
    private Enum _MethodType; 

    // Surrogate object property for MethodObject required by XmlSerializer 
    [XmlElement(Order = 1, ElementName = "MethodType")] 
    [Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DebuggerBrowsable(DebuggerBrowsableState.Never)] 
    public object MethodTypeObject 
    { 
     get { return MethodType; } 
     set { MethodType = (Enum)value; } 
    } 

    // Ignore the Enum member that cannot be serialized directly 
    [XmlIgnore] 
    public Enum MethodType 
    { 
     get { return _MethodType; } 
     set { _MethodType = value; } 
    } 
    public TESTCLASS() { } 

    public TESTCLASS(Enummies.BigMethods bigM) 
    { 
     MethodType = bigM; 
    } 
    public TESTCLASS(Enummies.SmallMethods smallM) 
    { 
     MethodType = smallM; 
    } 
} 

そしてXMLが生成されます。次のようにしたがって、あなたはあなたのタイプを変更することができますか?これは、要素がその型を明示的にアサートするのに使用できるW3C standard attributeです。マイクロソフトでは、hereのように、この属性を使用して多型要素の型情報を表します。

サンプルfiddle

値のタイプがMethodObject(ゲッターではありません)のセッターのタイプEnumであることを確認することができますが、これはXMLのシリアル化には必要ありません。

+0

XmlIncludesで潜在的な型を指定する限り、System.Objectのメンバーをシリアル化できることはわかりませんでした。なぜ私はあなたが見たものとは異なる例外を得ているのだろうかと思う。また、これらの属性は必要ですか?私は以前彼らを見たことがない。 "[ –

+1

@TalenKylon - これらの属性は必要ありません。[DebugableBrowsableState.Never]、[DebugableBrowsableState.Never]それらは、代理プロパティがデバッガおよびプロパティエディタに表示されないようにします。私が列挙した例外は、外側の属性ではなく内側の属性でした。また、直列化をテストする前に '[XmlInclude(typeof(Enummies.BigMethods)]'属性を追加しました。 – dbc

関連する問題