- .Net/C#アプリケーションでは、私は互いに参照を持つデータ構造を持っています。
- シリアル化すると、.Netは別のオブジェクトコピーを持つすべての参照をシリアル化します。
- 次の例では、「Person」の配列にシリアル化しようとしています
「Person」は別の人を参照している可能性があります。上記のコードで.net XMLシリアル化 - オブジェクトコピーの代わりに参照を格納する
public class Person { public string Name; public Person Friend; } Person p1 = new Person(); p1.Name = "John"; Person p2 = new Person(); p2.Name = "Mike"; p1.Friend = p2; Person[] group = new Person[] { p1, p2 }; XmlSerializer ser = new XmlSerializer(typeof(Person[])); using (TextWriter tw = new StreamWriter("test.xml")) ser.Serialize(tw,group); //above code generates following xml <ArrayOfPerson> <Person> <Name>John</Name> <Friend> <Name>Mike</Name> </Friend> </Person> <Person> <Name>Mike</Name> </Person> </ArrayOfPerson>
同じオブジェクトに対して2つの参照があるので、同じ「マイク」の目的は、二つの場所です。
- デシリアライズ中に、それらは2つの異なるオブジェクトになります。これらのオブジェクトは、シリアル化されたときの正確な状態ではありません。
- 私はこれを避け、シリアル化されたxmlでオブジェクトのコピーを持ちたいと思います。すべての参照はこのコピーを参照する必要があります。デシリアライズ後、私は元の同じデータ構造に戻りたいと思う。
- 可能でしょうか?
答えて
XmlSerializerでは不可能です。 PreserveObjectReferencesプロパティを使用してDataContractSerializerでこれを達成できます。詳細を説明しているpostをご覧ください。ここで
はサンプルコードです:
<ArrayOfPerson z:Id="1" z:Size="2" xmlns="http://schemas.datacontract.org/2004/07/ToDelete" xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/">
<Person z:Id="2">
<Friend z:Id="3">
<Friend i:nil="true"/>
<Name z:Id="4">Mike</Name>
</Friend>
<Name z:Id="5">John</Name>
</Person>
<Person z:Ref="3" i:nil="true"/>
</ArrayOfPerson>
今すぐコンストラクタでfalse
にPreserveObjectReferences
を設定し、この取得します:
<ArrayOfPerson xmlns="http://schemas.datacontract.org/2004/07/ToDelete" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<Person>
<Friend>
<Friend i:nil="true"/>
<Name>Mike</Name>
</Friend>
<Name>John</Name>
</Person>
<Person>
<Friend i:nil="true"/>
<Name>Mike</Name>
</Person>
</ArrayOfPerson>
を
public class Person
{
public string Name;
public Person Friend;
}
class Program
{
static void Main(string[] args)
{
Person p1 = new Person();
p1.Name = "John";
Person p2 = new Person();
p2.Name = "Mike";
p1.Friend = p2;
Person[] group = new Person[] { p1, p2 };
var serializer = new DataContractSerializer(group.GetType(), null,
0x7FFF /*maxItemsInObjectGraph*/,
false /*ignoreExtensionDataObject*/,
true /*preserveObjectReferences : this is where the magic happens */,
null /*dataContractSurrogate*/);
serializer.WriteObject(Console.OpenStandardOutput(), group);
}
}
これは、次のXMLを生成しますこのようにして生成されたXMLは、相互運用性がないDataContractSerializerを使用して逆シリアル化することしかできません(BinaryFormatterと同じ解説)。
ExtendedXmlSerializerを使用できます。
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
public Person Boss { get; set; }
}
public class Company
{
public List<Person> Employees { get; set; }
}
、あなたはこのように、循環参照を持つオブジェクトを作成します:ここでは、クラスを持っている場合は直列化の例object reference and circular reference
ある
var boss = new Person {Id = 1, Name = "John"};
boss.Boss = boss; //himself boss
var worker = new Person {Id = 2, Name = "Oliver"};
worker.Boss = boss;
var obj = new Company
{
Employees = new List<Person>
{
worker,
boss
}
};
あなたは、参照オブジェクトとしてPersonクラスを設定する必要があります:
var serializer = new ConfigurationContainer().ConfigureType<Person>()
.EnableReferences(p => p.Id)
.Create();
最後に、あなたのobjをシリアル化することができます電気ショック療法:
<?xml version="1.0" encoding="utf-8"?>
<Company xmlns="clr-namespace:ExtendedXmlSerializer.Samples.ObjectReference;assembly=ExtendedXmlSerializer.Samples">
<Employees>
<Capacity>4</Capacity>
<Person Id="2">
<Name>Oliver</Name>
<Boss Id="1">
<Name>John</Name>
<Boss xmlns:exs="https://extendedxmlserializer.github.io/v2" exs:entity="1" />
</Boss>
</Person>
<Person xmlns:exs="https://extendedxmlserializer.github.io/v2" exs:entity="1" />
</Employees>
</Company>
ExtendedXmlSerializerサポート.NET 4.5と.NETのコア:
var xml = serializer.Serialize(obj);
出力XMLは次のようになります。
あなたはあなた自身のソフトウェアを宣伝していることを言及する必要があります。これは、.netフレームワークの一部ではありませんが、良い仕事のように見えます – MikeT
- 1. ArrayListの参照の代わりに値を格納する
- 2. クラスから独立してXMLシリアル化メタデータを格納する
- 3. std :: vectorの代わりにオブジェクトのコピーではなく参照を格納する
- 4. Codeigniterに配列の代わりに値を格納する
- 5. xmlを使用する代わりにオブジェクトをシリアル化する利点
- 6. GenericXmlSecurityTokenを格納/逆シリアル化/シリアル化する方法は?
- 7. オブジェクトへの参照を格納する
- 8. XpsDocumentsをデータベースに格納するためにXMLにシリアル化できますか?
- 9. 空文字列の代わりにNULLを格納する
- 10. .NET XMLシリアル化と継承
- 11. protobuf-net文字列にシリアル化してデータベースに格納してからシリアル化する
- 12. Laravelに参照配列を格納
- 13. メモリの代わりにflipflopsにビットベクトルを格納Chiesel
- 14. XMLシリアル化 - .NET 4.0の別の結果
- 15. C#でオブジェクトの参照をリストに格納する方法は?
- 16. 参照型変数の初期化と格納
- 17. DOM要素への参照の格納
- 18. AVPlayerItemのコピーを何らかの形で生成する代わりに、参照にアクセスする代わりに
- 19. JSON:{name:name、value:value}の代わりにname:valueに辞書をJSONシリアル化
- 20. .NET WebServiceはJSONの代わりにXMLを返します
- 21. は、表ヘッダで列を参照する代わりに手紙
- 22. .NET JsonExtensionData Xml逆シリアル化の類推
- 23. シリアル化されたオブジェクトをSQL Serverデータベースに格納するために使用するシリアル化形式
- 24. 別の変数に参照を格納する
- 25. インスタンスの参照をクラスコンストラクタに格納する方法
- 26. データベースエントリへの参照を変数に格納する効率
- 27. 複数のイメージ参照をデータベースフィールドに格納する方法
- 28. Java:グリッド参照を格納するのに最適なタイプ
- 29. xmlをxmlに格納
- 30. C#:レジストリへの.Netオブジェクトの格納
BinaryFormatterとSoapFormatterが参照値を保持していることがわかりました。 – Palani
SoapFormatterは非推奨であり、ジェネリックはサポートしていません。 –