2

次の過度に単純化されたXMLのチャンクについて考えてみます。

<ElementA>
   <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#integer">5
   </AttributeValue>
</ElementA>

具体的には、DataType属性からAttributeValue要素を見ると、私の値が整数型であることがわかります(ただし、double、string、datetime ... w3標準から確立されたデータ型である可能性があります)。このxmlを強く型付けされた値を持つ.NETクラスに逆シリアル化したいです。私が最初に頭に浮かんだのは、ジェネリックAttributeValueクラスを作成することです。

public class AttributeValue<T>
{
    public T Value {get; set;}
}

しかしもちろん、これはいくつかの理由で機能しません-最大の理由は、Tが定義されていないためにコンパイルされない親クラスで型を宣言する必要があることです:

public class ElementA
{
    public AttributeValue<T> {get; set; }  // Naturally, this will not work because T
}                                          // is not defined.

さらに、カスタムシリアル化を処理するには、クラスにIXmlSerializableを実装する必要があります。

この問題を解決するためのより良い方法はありますか?コードでDataType属性をシリアル化し、値を文字列として格納し、後で変換できることはわかっていますが、後で処理するために、ビジネスオブジェクトに正しい型を実際に含めると便利です。

助けてくれてありがとう!

ジェイソン

4

3 に答える 3

2

これがあなたの質問に対する正確な答えではないことはわかっていますが、.Net 4 でダイナミクスを使用してソリューションを実装できます。以下に例を示します。

public class DynamicElement : DynamicObject
{
    public Dictionary<string, object> Attributes
    {
        get { return lst; }
    }

    private Dictionary<string, object> lst;

    public DynamicElement()
    {
        lst = new Dictionary<string, object>(StringComparer.InvariantCultureIgnoreCase);
    }

    public bool Present(string name)
    {
        if (lst == null) return false;
        if (!lst.ContainsKey(name)) return false;

        return true;
    }

    public override bool TryGetMember(GetMemberBinder binder, out object result)
    {
        var name = binder.Name;
        result = null;

        if (lst == null) return false;
        if (!lst.ContainsKey(name)) return false;

        result = lst[name];
        return true;
    }
    public override bool TrySetMember(SetMemberBinder binder, object value)
    {
        var name = binder.Name;

        if (lst == null) return false;

        if (!lst.ContainsKey(name))
            lst.Add(name, value);
        else
            lst[name] = value;

        return true;
    }
}

そして、それを使用するには、次のようになります。

dynamic d = new DynamicElement();
d.AttributeValue = Convert.ToInt32(xmlElement.Value);
d.Done = true; //just another example.

後で:

public void something(DynamicElement de)
{
    dynamic d = de;
    if(d.Done) //remember, defined this above.. just an example.
    {
        int someValue = d.AttributeValue;
    }
}

欠点は、インテリセンスがないことです。実行時にすべて解決されます。d.Present("AttributeName");コンパイルがうまくいかない場合は、Sorry で値が存在するかどうかを確認することもできます。メモ帳に書きました:)

編集:

シリアライゼーションの実装も難しくありません。属性ディクショナリを反復処理するだけでよいからです。

于 2012-05-25T16:14:57.473 に答える
0

あなたがやろうとしていることは、実際にはできません。動的構造 (データ フィールドを任意の型にすることができる XML) があり、クラス内に厳密に型指定された定義が必要な場合。厳密に型指定する場合は、コンパイル時の型を知っている必要がありますが、それはわかりません。@caesay の提案は良いものです。または単にデータを表現するObjectことも同様に機能しますが、コンパイル時に情報がわからない場合、コンパイラ チェック (つまり、厳密な型指定) を行うことはできません。

于 2012-05-25T16:33:52.470 に答える