Search code examples
c#.netopenxmlopenxml-sdk

OpenXML: Difference of using Element.Val and Element{ Val = "Val" }


Basically, this

pRp.GetFirstChild<ParagraphStyleId>().Val = "Heading1";

and this

pRp.GetFirstChild<ParagraphStyleId>().Remove();
                    pRp.InsertAt(new ParagraphStyleId() { Val = "Heading1" }, 0);

is giving me different results. The latter one works as expected. The first one doesn't. Why?

What I am trying to do is setting the first paragraph of the document to a style of Heading1, whether or not ParagraphStyleId is present, or if another style has been set.

Also, is there a better way to do this?

Thanks!


Solution

  • For you to understand the complete scenario you need to understand the diference between reference types and value types. Only C# 7.0 and later versions supports returning ref types: https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/ref-returns

    In the first scenario:

    pRp.GetFirstChild<ParagraphStyleId>()
    

    The function GetFirstChild needs to return a reference in order for the modifications of the val property changes the pRp object. Remember that the default behavior returns a shallow copy of the desired object. So any changes you make is apply to the copy and not the parent object.

    In the second case:

    pRp.GetFirstChild<ParagraphStyleId>().Remove();
    

    This line operates directly on the parent object, this is why is capable of removing the object.

    pRp.InsertAt(new ParagraphStyleId() { Val = "Heading1" }, 0);
    

    And finally in here you are operating once again on the parent instance by appending a new object into it.

    The main difference is that in the first case you are operating on a copy of the ParagraphStyleId object and in the second you are working directly on the parent instance which is pRp.