.net XML Serialization - Хранение Ссылки вместо Объектной Копии

Много замечательных ответов на эти вопросы, спасибо людям. Я хотел бы поместить здесь редактируемый ответ, который объединяет вещи.

Для тех, кто знаком с пониманием C # -> то же самое, что и выражение> lamba - хороший первый шаг. Это использование: -

fun x y -> x + y + 1

Можно понимать как эквивалент: -

(x, y) => x + y + 1;

Однако ясно, что -> имеет более фундаментальное значение, которое вытекает из концепции, что функция который принимает два параметра, таких как приведенный выше, может быть уменьшен (это правильный термин?) до ряда функций, принимающих только один параметр.

Следовательно, когда вышеизложенное описывается следующим образом: -

Int -> Int -> Int

Это действительно помогло узнать, что -> является правой ассоциативной, следовательно, вышеизложенное можно рассмотреть: -

Int -> (Int -> Int)

Ага! У нас есть функция, которая принимает Int и возвращает (Int -> Int) (карри функция?).

Также помогло объяснение, что -> может также появиться как часть определения типа. (Int -> Int) - это тип любой функции, которая принимает Int и возвращает Int.

Также полезно -> появляется в другом синтаксисе, таком как сопоставление, но там это не имеет того же значения? Это верно? Я не уверен, что это так. Я подозреваю, что это имеет то же значение, но у меня пока нет слов, чтобы выразить это.

Обратите внимание, что цель этого ответа не в том, чтобы создавать дальнейшие ответы, а в том, чтобы вы, люди, совместно редактировали его, чтобы создать более точный ответ. Крайне было бы хорошо, чтобы все неопределенности и ошибки (такие как этот параграф) были удалены и добавлены лучшие примеры. Давайте постараемся сделать этот ответ как можно более доступным для непосвященных.

34
задан RedGlyph 24 October 2009 в 10:22
поделиться

1 ответ

Это невозможно с XmlSerializer . Этого можно добиться с помощью DataContractSerializer , используя свойство PreserveObjectReferences . Вы можете ознакомиться с этим сообщением , в котором объясняются подробности.

Вот пример кода:

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:

<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>

Теперь установите PreserveObjectReferences на false в конструкторе, и вы получите следующее:

<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>

Стоит отметить, что XML, созданный таким образом, не совместим и может быть десериализован только с помощью DataContractSerializer (то же замечание, что и для BinaryFormatter ).

35
ответ дан 27 November 2019 в 17:08
поделиться
Другие вопросы по тегам:

Похожие вопросы: