Spire.Doc Version 14.10.9 — Detailed Upgrade Changes vs. 14.9.11

Summary

This upgrade contains several high-risk public API changes. The wholesale renumbering of the DocumentObjectType enum is the highest-risk item: without a recompile it causes silent behavioural errors.

1. Comparison Targets and File Information

Item 14.9.11 14.10.9
Assembly Spire.Doc.dll Spire.Doc.dll
Path E:\packges\netdll\spire.doc_14.9.11\BIN\NET4.6\Spire.Doc.dll E:\packges\netdll\spire.doc_14.10.6\BIN\NET4.6\Spire.Doc.dll
AssemblyVersion 14.9.11.0 14.10.9.0
FileVersion 14.9.11.3046 14.10.9.3046
File size 20,976,616 bytes 21,020,672 bytes (+44,056)
SHA256 9bc4566b89b5cb1abe82a9fcbb726ce20a2edfd0b7b2f6657e1b68b6bf35f1e5 5a9ba3712321fcc3f91b1273927b4714933a726ffce1cbe6e6b4f148ee6cd0a3
Public key token 663f351905198cb3 663f351905198cb3 (same strong name)
XML documentation 1,215,855 bytes 1,266,435 bytes (+50,580)

The referenced-assembly lists of the two versions are identical (HarfBuzzSharp, mscorlib, System, System.Core, System.Data, System.Drawing, System.Web, System.Windows.Forms, System.Xml); no assembly dependency was added or removed.

Note: the assembly version has changed. .NET Framework strong-name binding does not automatically accept a higher version; without a bindingRedirect, older applications may fail at load time.

2. Statistics Overview

Metric 14.9.11 14.10.9 Change
Public types 508 507 +8 / -9
Public members (DeclaredOnly) 5460 5527 +178 / -111 / ~97
Types added — 8 See Appendix A
Types removed 9 — See Appendix B
Members added — 178 37 introduced with new types, 141 added to existing types
Members removed 111 — 28 removed with their types; 83 on surviving types
of which: directly declared removals — 54 Neither the type nor any ancestor provides them in the new version
of which: still reachable by inheritance — 29 Moved up to a base class; 2 of them changed signature
Members modified — 97 60 enum values + 37 non-enum modifications
Effective member surface lost — 250 slots / 67 types 90 unique signatures after deduplication
Effective member surface gained — 917 slots / 112 types Mainly from new base classes / new interfaces
Type metadata changes — 114 Base class, interfaces, abstractness, etc.
XML docId match rate 77.8% 77.7% Used for cross-validation only; does not affect conclusions

Counting conventions:

3. Highest-Priority Breaking Changes

3.1 Wholesale renumbering of the DocumentObjectType enum (highest risk: silent errors)

64 constants in the old version, 62 in the new: 4 SDT content constants removed, 2 SDT Mark constants added, and the numeric value of nearly every constant has changed.

Complete mapping table (only changed entries listed)

Member Old value New value Status
Document 0 1 Value changed
Section 1 2 Value changed
Body 2 3 Value changed
HeaderFooter 3 4 Value changed
Paragraph 4 5 Value changed
StructureDocumentTag 5 6 Value changed
StructureDocumentTagInline 6 9 Value changed
StructureDocumentTagMarkStart — 7 Added
StructureDocumentTagRow 7 10 Value changed
StructureDocumentTagCell 8 11 Value changed
StructureDocumentTagMarkEnd — 8 Added
SDTBlockContent 9 — Removed
SDTInlineContent 10 — Removed
SDTRowContent 11 — Removed
SDTCellContent 12 — Removed
Table 13 12 Value changed
TableRow 14 13 Value changed
TableCell 15 14 Value changed
TextRange 16 15 Value changed
Picture 17 16 Value changed
FieldStart 18 17 Value changed
Field 19 18 Value changed
FieldMark 20 19 Value changed
FieldSeparator 21 20 Value changed
FieldEnd 22 21 Value changed
MergeField 23 22 Value changed
SeqField 24 23 Value changed
EmbededField 25 24 Value changed
ControlField 26 25 Value changed
TextFormField 27 26 Value changed
DropDownFormField 28 27 Value changed
CheckBox 29 28 Value changed
BookmarkStart 30 29 Value changed
BookmarkEnd 31 30 Value changed
MoveFromRangeStart 32 31 Value changed
MoveFromRangeEnd 33 32 Value changed
MoveToRangeStart 34 33 Value changed
MoveToRangeEnd 35 34 Value changed
PermissionStart 36 35 Value changed
PermissionEnd 37 36 Value changed
Shape 38 37 Value changed
ShapeGroup 39 38 Value changed
ShapeLine 40 39 Value changed
ShapePath 41 40 Value changed
ShapeRect 42 41 Value changed
Comment 43 42 Value changed
Footnote 44 43 Value changed
TextBox 45 44 Value changed
Break 46 45 Value changed
Symbol 47 46 Value changed
TOC 48 47 Value changed
XmlParaItem 49 48 Value changed
Undefined 50 -2 Value changed
CommentMark 51 49 Value changed
OleObject 52 50 Value changed
CustomXml 53 51 Value changed
SmartTag 54 52 Value changed
OfficeMath 55 53 Value changed
System 56 -1 Value changed
Ruby 57 54 Value changed
SubDocument 58 55 Value changed
SpecialChar 59 56 Value changed
GlossaryDocument 60 57 Value changed
BuildingBlock 61 58 Value changed
FormField 62 59 Value changed
Any 63 0 Value changed

Complete value sequence in the old version

Document=0, Section=1, Body=2, HeaderFooter=3, Paragraph=4, StructureDocumentTag=5, StructureDocumentTagInline=6, StructureDocumentTagRow=7, StructureDocumentTagCell=8, SDTBlockContent=9, SDTInlineContent=10, SDTRowContent=11, SDTCellContent=12, Table=13, TableRow=14, TableCell=15, TextRange=16, Picture=17, FieldStart=18, Field=19, FieldMark=20, FieldSeparator=21, FieldEnd=22, MergeField=23, SeqField=24, EmbededField=25, ControlField=26, TextFormField=27, DropDownFormField=28, CheckBox=29, BookmarkStart=30, BookmarkEnd=31, MoveFromRangeStart=32, MoveFromRangeEnd=33, MoveToRangeStart=34, MoveToRangeEnd=35, PermissionStart=36, PermissionEnd=37, Shape=38, ShapeGroup=39, ShapeLine=40, ShapePath=41, ShapeRect=42, Comment=43, Footnote=44, TextBox=45, Break=46, Symbol=47, TOC=48, XmlParaItem=49, Undefined=50, CommentMark=51, OleObject=52, CustomXml=53, SmartTag=54, OfficeMath=55, System=56, Ruby=57, SubDocument=58, SpecialChar=59, GlossaryDocument=60, BuildingBlock=61, FormField=62, Any=63

Complete value sequence in the new version

Undefined=-2, System=-1, Any=0, Document=1, Section=2, Body=3, HeaderFooter=4, Paragraph=5, StructureDocumentTag=6, StructureDocumentTagMarkStart=7, StructureDocumentTagMarkEnd=8, StructureDocumentTagInline=9, StructureDocumentTagRow=10, StructureDocumentTagCell=11, Table=12, TableRow=13, TableCell=14, TextRange=15, Picture=16, FieldStart=17, Field=18, FieldMark=19, FieldSeparator=20, FieldEnd=21, MergeField=22, SeqField=23, EmbededField=24, ControlField=25, TextFormField=26, DropDownFormField=27, CheckBox=28, BookmarkStart=29, BookmarkEnd=30, MoveFromRangeStart=31, MoveFromRangeEnd=32, MoveToRangeStart=33, MoveToRangeEnd=34, PermissionStart=35, PermissionEnd=36, Shape=37, ShapeGroup=38, ShapeLine=39, ShapePath=40, ShapeRect=41, Comment=42, Footnote=43, TextBox=44, Break=45, Symbol=46, TOC=47, XmlParaItem=48, CommentMark=49, OleObject=50, CustomXml=51, SmartTag=52, OfficeMath=53, Ruby=54, SubDocument=55, SpecialChar=56, GlossaryDocument=57, BuildingBlock=58, FormField=59

Why this is the highest risk: the C# compiler inlines const enum values into the calling assembly. Existing assemblies do not re-read the new DLL's enum values at runtime; they keep using the old numbers from compile time. For example:

Constant in old code (old value) What that value means in the new version Consequence
Document (0) Any (0) A document node is treated as an arbitrary node
Body (2) Section (2) Body is treated as a section
Paragraph (4) HeaderFooter (4) A paragraph is treated as a header/footer
StructureDocumentTag (5) Paragraph (5) An SDT is treated as a paragraph
Table (13) TableRow (13) A table is treated as a row
TableCell (15) TextRange (15) A cell is treated as a text range
Field (19) FieldMark (19) A field is treated as a field mark
PermissionStart (36) PermissionEnd (36) Permission start/end are swapped
Shape (38) ShapeGroup (38) A shape is treated as a shape group
Comment (43) Footnote (43) A comment is treated as a footnote
Break (46) Symbol (46) A line break is treated as a symbol
Undefined (50) OleObject (50) An undefined value is treated as an OLE object
System (56) SpecialChar (56) A system node is treated as a special character
Any (63) No definition (max in the new enum is 59) Out of range / undefined behaviour

In addition, default(DocumentObjectType) now means Any instead of Document. Any code relying on the default value, numeric comparison, serialization/deserialization, database storage or caching must be migrated.

Remediation:

  1. All consumers must be recompiled against the new DLL; replacing the DLL alone is not enough.
  2. Remove numeric literals from the code (such as (DocumentObjectType)4) and use the constant names.
  3. If enum values were ever persisted, build a mapping from "old constant name → new constant name" and take the new values; do not carry the numbers over directly.
  4. Check that switch statements cover the new values; old value 63 (Any) has no corresponding member in the new version.

3.2 Permission identifiers change from string to int

Type/member 14.9.11 14.10.9 Impact
Permission.Id string int Return type change; breaks both binary and source
Permission.EditorGroup get get/set Setter added; compatible
Permission constructors Permission(PermissionStart), Permission(PermissionStart, PermissionEnd) All removed Breaks source and binary
Permission.Editor — string get/set Added
Permission.Remove() — void Added
PermissionStart constructor (IDocument, string id) (IDocument, int id) Parameter type change
PermissionStart.Id string int Return type change
PermissionStart.Permission — Permission get Added; replaces the old constructors
PermissionEnd constructor (IDocument, string id) (IDocument, int id) Parameter type change
PermissionEnd.Id string int Return type change
PermissionEnd.PermissionStart — PermissionStart get Added
PermissionCollection.FindById FindById(string) FindById(int) Parameter type change
PermissionCollection indexer this[string id] Removed Use this[int index] / FindById(int)
PermissionCollection.Remove Remove(Permission) Remove(Permission) + Remove(int id) Removal by id added
PermissionCollection.Count/GetEnumerator — Added Added
Paragraph.AppendPermStart/End (string id) (int id) Parameter type change

Migration example:

// Old code
var start = new PermissionStart(doc, "editor-1");
var permission = new Permission(start);
string id = permission.Id;
var found = doc.Permissions.FindById("editor-1");
var byKey = doc.Permissions["editor-1"];       // old indexer
doc.Permissions.Remove(byKey);                  // old removal by object

// New code
var start = new PermissionStart(doc, 1);
var permission = start.Permission;            // no public constructor any more
int id = permission.Id;
permission.Editor = "editor-1";               // newly added string identifier
var found = doc.Permissions.FindById(1);
doc.Permissions.Remove(1);                     // newly added removal by id

If the business layer used strings as permission keys, you need to decide on the new integer ID allocation scheme (for example a database identity column or an in-document sequence number) and make sure PermissionStart, PermissionEnd and Permission all use the same integer.

3.3 SDT (Structured Document Tag) model restructuring

Removed types: Spire.Doc.Documents.SDTContent (base class Body), Spire.Doc.Documents.SDTInlineContent (base class DocumentObject).

Added types: StructureDocumentTagMarkStart, StructureDocumentTagMarkEnd (both inherit directly from ParagraphBase and expose only DocumentObjectType).

Structural changes:

Type Old base class New base class Key result
StructureDocumentTag BodyRegion BodyRegion (unchanged) SDTContent property removed; Body (IBody) added
StructureDocumentTagInline ParagraphBase CompositeDocumentObject SDTContent removed; Items/Text/TextNodes/CharacterFormat/revision properties added
StructureDocumentTagRow TableRow CompositeDocumentObject No longer a TableRow; loses Cells/RowFormat/Height/HeightType/Hidden/IsHeader/AddCell/GetRowIndex etc.
StructureDocumentTagCell TableCell CompositeDocumentObject No longer a TableCell; loses 27 effective members including CellFormat/Width/Scaling/GridSpan/Paragraphs/Tables/FormFields/OwnerRow/SplitCell

How Row is constructed: StructureDocumentTagRow(Table ownerTable) is removed; StructureDocumentTagRow(Document doc) is added. How Cell is constructed: StructureDocumentTagCell(TableRow ownerRow) is removed; StructureDocumentTagCell(Document doc) is added.

Impact: any code that uses SDT rows/cells as ordinary table rows/cells (styling, row height, cell width, merging, splitting, XHTML insertion, iterating Table.Rows/Table.Cells) will either fail to compile or, at runtime, no longer recognise them as table structure. The new version turns them into "composite objects with child nodes"; contents are accessed through CompositeDocumentObject's DOM API (ChildObjects, AppendChild, InsertBefore, etc.). This is a semantic-level restructuring and cannot be solved by type casts alone.

Migration example:

// Old code
StructureDocumentTag sdt = new StructureDocumentTag(doc);
SDTContent content = sdt.SDTContent;
content.AddParagraph();

// New code
StructureDocumentTag sdt = new StructureDocumentTag(doc);
IBody body = sdt.Body;
body.AddParagraph();

// Old code: SDT cell as a TableCell
StructureDocumentTagCell cell = new StructureDocumentTagCell(row);
cell.CellFormat.Width = 100;

// New code: no more CellFormat; use CompositeDocumentObject child/child-content APIs
StructureDocumentTagCell cell = new StructureDocumentTagCell(doc);
// Concrete cell formatting must be achieved through child nodes or by redesigning the document structure; regression testing is required

3.4 Collection hierarchy restructuring

Core changes:

Overview of base-class changes (collection-related):

Type Old base class/state New base class/state Result
DocumentObjectCollection DocumentItemCollectionBase (abstract) OwnerHolder (non-abstract) Abstractness change; Add returns void
DocumentSubsetCollection OwnerHolder Type removed Old base class of Paragraph/Table collections
CommentsCollection DocumentItemCollectionBase DocumentObjectCollection Gains Count/Add/Remove/ToArray etc.
FieldCollection DocumentItemCollectionBase DocumentObjectCollection Gains collection operations; ToArray added
FormFieldCollection DocumentItemCollectionBase DocumentObjectCollection Gains collection operations; ToArray added
TextBoxCollection DocumentItemCollectionBase DocumentObjectCollection Indexer return type changes to ShapeObject
ParagraphCollection DocumentSubsetCollection DocumentObjectCollection Constructor parameter changes to CompositeDocumentObject; Add returns void
TableCollection DocumentSubsetCollection DocumentObjectCollection Constructor parameter changes to CompositeDocumentObject; Add returns void
BookmarkCollection DocumentItemCollectionBase OwnerHolder Gains Count/GetEnumerator/Remove(string)/ResetBookmarkCache
PermissionCollection DocumentItemCollectionBase OwnerHolder FindById(int)/Remove(int)/Count/GetEnumerator
ShapeItemCollection DocumentObjectCollection DocumentItemCollectionBase Loses Add/Clear/Contains/IndexOf/Insert/Remove/RemoveAt/FirstItem/Item/LastItem/Owner — 11 items in total
HeadersFooters OwnerHolder DocumentObjectCollection Gains Count/Add/Remove/ToArray and 19 items in total

Members whose Add return type changes from int to void (binary-breaking):

Migration example:

// Old code: relies on the returned index
int index = body.ChildObjects.Add(paragraph);
int index2 = body.Paragraphs.Add(paragraph);

// New code: Add returns void; call IndexOf yourself when you need the index
body.ChildObjects.Add(paragraph);
int index = body.ChildObjects.IndexOf(paragraph);
body.Paragraphs.Add(paragraph);
int index2 = body.Paragraphs.IndexOf(paragraph);

// Old code: strongly typed overloads
row.Cells.Add(cell);
table.Rows.Insert(0, row);

// New code: use the DocumentObject overloads (they return void)
row.Cells.Add((DocumentObject)cell);
table.Rows.Insert(0, (DocumentObject)row);

3.5 Base-class changes (19 types)

Base-class changes affect inherited members, is/as casting, overrides, serialization and binary member resolution all at once.

Type Old base class New base class
Spire.Doc.Collections.BookmarkCollection Spire.Doc.Collections.DocumentItemCollectionBase Spire.Doc.OwnerHolder
Spire.Doc.Collections.CommentsCollection Spire.Doc.Collections.DocumentItemCollectionBase Spire.Doc.Collections.DocumentObjectCollection
Spire.Doc.Collections.DocumentObjectCollection Spire.Doc.Collections.DocumentItemCollectionBase Spire.Doc.OwnerHolder
Spire.Doc.Collections.FieldCollection Spire.Doc.Collections.DocumentItemCollectionBase Spire.Doc.Collections.DocumentObjectCollection
Spire.Doc.Collections.FormFieldCollection Spire.Doc.Collections.DocumentItemCollectionBase Spire.Doc.Collections.DocumentObjectCollection
Spire.Doc.Collections.ParagraphCollection Spire.Doc.Collections.DocumentSubsetCollection Spire.Doc.Collections.DocumentObjectCollection
Spire.Doc.Collections.PermissionCollection Spire.Doc.Collections.DocumentItemCollectionBase Spire.Doc.OwnerHolder
Spire.Doc.Collections.ShapeItemCollection Spire.Doc.Collections.DocumentObjectCollection Spire.Doc.Collections.DocumentItemCollectionBase
Spire.Doc.Collections.TableCollection Spire.Doc.Collections.DocumentSubsetCollection Spire.Doc.Collections.DocumentObjectCollection
Spire.Doc.Collections.TextBoxCollection Spire.Doc.Collections.DocumentItemCollectionBase Spire.Doc.Collections.DocumentObjectCollection
Spire.Doc.Documents.StructureDocumentTagCell Spire.Doc.TableCell Spire.Doc.CompositeDocumentObject
Spire.Doc.Documents.StructureDocumentTagInline Spire.Doc.Fields.ParagraphBase Spire.Doc.CompositeDocumentObject
Spire.Doc.Documents.StructureDocumentTagRow Spire.Doc.TableRow Spire.Doc.CompositeDocumentObject
Spire.Doc.Fields.Comment Spire.Doc.Fields.ParagraphBase Spire.Doc.Fields.InlineBody
Spire.Doc.Fields.Footnote Spire.Doc.Fields.ParagraphBase Spire.Doc.Fields.InlineBody
Spire.Doc.Fields.OMath.OfficeMath Spire.Doc.Fields.ParagraphBase Spire.Doc.CompositeDocumentObject
Spire.Doc.Fields.Shapes.ShapeBase Spire.Doc.Fields.ParagraphBase Spire.Doc.CompositeDocumentObject
Spire.Doc.Fields.TableOfContent Spire.Doc.Fields.ParagraphBase Spire.Doc.Fields.Field
Spire.Doc.HeadersFooters Spire.Doc.OwnerHolder Spire.Doc.Collections.DocumentObjectCollection

Key impacts:

3.6 Base-class member moves down and cascading loss

The following members move down from DocumentObject to CompositeDocumentObject:

As a result: composite types (Body, Section, Table, TableRow, TableCell, Document, Paragraph, Comment, Footnote, shapes, etc.) can still reach them through the new base class; but DocumentObject itself and 24 non-composite leaf types (BookmarkStart/End, Break, Field, TextRange, Symbol, PermissionStart/End, watermark types, etc.) no longer expose these members.

Member signature Number of affected types
method|ToString(System.String) 48
method|GetIndex(Spire.Doc.Interface.IDocumentObject) 24
property|ChildObjects() 24
property|FirstChild() 24
property|LastChild() 24
method|ApplyCharacterFormat(Spire.Doc.Formatting.CharacterFormat) 11
method|NameToBuiltIn(System.String) 4
method|EnsureMinimum() 3
ctor|(Spire.Doc.Collections.BodyRegionCollection) 2
ctor|(Spire.Doc.Document) 2

Explanation: ToString(string) disappears from 48 types because it is removed from the DocumentObject base class; ApplyCharacterFormat disappears from 11 types because those types no longer inherit ParagraphBase (ParagraphBase itself still keeps the method).

Binary impact: members moving up to a base class usually still resolve (the CLR walks up the base-class chain); members moving down to a derived class are different — member references in old IL usually point at the original declaring type DocumentObject, and the CLR does not search derived classes, so after replacing the DLL a MissingMethodException is very likely. Therefore "still reachable through the new base class" holds only for recompiled source; it does not make old binaries safe.

3.7 Return type changes (21 items)

Type Member Old return type New return type
Spire.Doc.BodyRegion Spire.Doc.Interface.IBody OwnerTextBody { get; } Spire.Doc.Body Spire.Doc.Interface.IBody
Spire.Doc.Collections.DocumentObjectCollection System.Void Add(Spire.Doc.Interface.IDocumentObject documentObject) System.Int32 System.Void
Spire.Doc.Collections.ParagraphCollection override System.Void Add(Spire.Doc.Interface.IParagraph paragraph) System.Int32 System.Void
Spire.Doc.Collections.ParagraphItemCollection Spire.Doc.Interface.IParagraphBase this[System.Int32 index] { get; } Spire.Doc.Fields.ParagraphBase Spire.Doc.Interface.IParagraphBase
Spire.Doc.Collections.TableCollection override System.Void Add(Spire.Doc.Interface.ITable table) System.Int32 System.Void
Spire.Doc.Collections.TableCollection System.Void Insert(System.Int32 index, Spire.Doc.Interface.ITable table) System.Int32 System.Void
Spire.Doc.Collections.TextBoxCollection Spire.Doc.Fields.ShapeObject this[System.Int32 index] { get; } Spire.Doc.Fields.TextBox Spire.Doc.Fields.ShapeObject
Spire.Doc.Documents.Paragraph Spire.Doc.Interface.IParagraphBase this[System.Int32 index] { get; } Spire.Doc.Fields.ParagraphBase Spire.Doc.Interface.IParagraphBase
Spire.Doc.Documents.TextBodySelection Spire.Doc.Interface.IBody TextBody { get; } Spire.Doc.Body Spire.Doc.Interface.IBody
Spire.Doc.Document Spire.Doc.Interface.IParagraphBase CreateParagraphItem(Spire.Doc.Documents.ParagraphItemType itemType) Spire.Doc.Fields.ParagraphBase Spire.Doc.Interface.IParagraphBase
Spire.Doc.Fields.Comment Spire.Doc.Interface.IBody Body { get; } Spire.Doc.Body Spire.Doc.Interface.IBody
Spire.Doc.Fields.Footnote Spire.Doc.Interface.IBody Body { get; } Spire.Doc.Body Spire.Doc.Interface.IBody
Spire.Doc.Fields.TextBox Spire.Doc.Interface.IBody Body { get; } Spire.Doc.Body Spire.Doc.Interface.IBody
Spire.Doc.Interface.IParagraphCollection System.Void Add(Spire.Doc.Interface.IParagraph paragraph) System.Int32 System.Void
Spire.Doc.Interface.IParagraph Spire.Doc.Interface.IParagraphBase this[System.Int32 index] { get; } Spire.Doc.Fields.ParagraphBase Spire.Doc.Interface.IParagraphBase
Spire.Doc.Interface.ITableCollection System.Void Add(Spire.Doc.Interface.ITable table) System.Int32 System.Void
Spire.Doc.Interface.ITextBox Spire.Doc.Interface.IBody Body { get; } Spire.Doc.Body Spire.Doc.Interface.IBody
Spire.Doc.Pages.FixedLayoutColumn Spire.Doc.Interface.IBody Body { get; } Spire.Doc.Body Spire.Doc.Interface.IBody
Spire.Doc.PermissionEnd System.Int32 Id { get; } System.String System.Int32
Spire.Doc.PermissionStart System.Int32 Id { get; } System.String System.Int32
Spire.Doc.Permission System.Int32 Id { get; } System.String System.Int32

Pattern summary:

All of these changes alter CLR method signatures (the return type is part of the signature); old binaries will get MissingMethodException, and at source level an explicit cast or a switch to the interface is usually required.

3.8 Type removals and namespace migration

9 removed public types:

Removed type Kind Member count Base class/notes
Spire.Doc.Collections.DocumentObjectCollection+ChangeItems Delegate 4 System.MulticastDelegate
Spire.Doc.Collections.DocumentObjectCollection+ChangeItemsType Enum 3 System.Enum
Spire.Doc.Collections.DocumentSubsetCollection Class 5 Spire.Doc.OwnerHolder
Spire.Doc.Collections.DocumentSubsetCollection+SubSetEnumerator Class 4 System.Object
Spire.Doc.CompoundFile.IDocCloneable Interface 1 —
Spire.Doc.Documents.IWSectionCollection Interface 3 —
Spire.Doc.Documents.SDTContent Class 1 Spire.Doc.Body
Spire.Doc.Documents.SDTInlineContent Class 5 Spire.Doc.DocumentObject
Spire.Doc.Interface.ITextBoxItemCollection Interface 2 —

8 added public types:

Added type Kind Member count Base class/notes
Spire.Doc.Collections.CommentRangeCollection Class 8 Spire.Doc.OwnerHolder
Spire.Doc.Collections.TextRangeCollection Class 2 Spire.Doc.Collections.DocumentObjectCollection
Spire.Doc.Documents.ISectionCollection Interface 0 —
Spire.Doc.Documents.StructureDocumentTagMarkEnd Class 1 Spire.Doc.Fields.ParagraphBase
Spire.Doc.Documents.StructureDocumentTagMarkStart Class 1 Spire.Doc.Fields.ParagraphBase
Spire.Doc.Fields.InlineBody Class 16 Spire.Doc.CompositeDocumentObject
Spire.Doc.Formatting.Revisions.IRevisionTracking Interface 8 —
Spire.Doc.Interface.IDocCloneable Interface 1 —

Key points:

4. Other Breaking and Behavioural Changes

4.1 Constructor and parameter type changes

Type Old constructor New constructor
Bookmark Bookmark(BookmarkStart start) Removed (two-parameter constructor retained)
PermissionStart (IDocument, string id) (IDocument, int id)
PermissionEnd (IDocument, string id) (IDocument, int id)
StructureDocumentTagRow (Table ownerTable) (Document doc)
StructureDocumentTagCell (TableRow ownerRow) (Document doc)
CellCollection (TableRow owner) (CompositeDocumentObject container)
RowCollection (Table owner) (CompositeDocumentObject container)
ParagraphCollection (BodyRegionCollection bodyItems) (CompositeDocumentObject ownerBody)
TableCollection (BodyRegionCollection bodyItems) (CompositeDocumentObject container)
CommentsCollection (Document doc) Removed
SectionCollection (Document doc) Removed
BodyRegionCollection (Body body) Removed
SDTProperties (DocumentObject owner) Removed
Permission Two public constructors All removed
TextBodySelection (ParagraphBase, ParagraphBase) (IParagraphBase, IParagraphBase)

Parameter name changes (only affect named arguments; source is generally compatible):

4.2 Directly declared removals (54 items)

These are members declared on the old type itself that are removed in the new version; they exclude inherited members that the old type loses because of a base-class change. The latter are counted in the effective member surface (250 slots across 67 types), typically the cascading disappearance of ChildObjects, ToString(string) and ApplyCharacterFormat.

The full list is in Appendix D. The non-cascading items that need the most attention:

Type Member Replacement/notes
Style/ListStyle/ParagraphStyle/TableStyle static BuiltinStyle NameToBuiltIn(string) No direct replacement
TextBodyPart Copy(ParagraphBase, bool), PasteAfter(ParagraphBase) Switch to the IParagraphBase overloads
TextBodySelection ctor(ParagraphBase, ParagraphBase) Switch to the IParagraphBase overload
OfficeMath ParentParagraph Switch to OwnerParagraph
Comment Items, EnsureMinimum() Items → CommentedItems; no direct replacement for EnsureMinimum
Footnote TextBody, EnsureMinimum() Footnote is itself an IBody; no direct replacement for EnsureMinimum
Paragraph AppendPermStart(string), AppendPermEnd(string) Switch to the int overloads
DocumentObject virtual ToString(string separator) No direct replacement
SDT types SDTContent property / SDT Row's Cells, RowFormat See 3.3
CommentsCollection Counts(), Remove(Comment) Count; Remove(DocumentObject)/Comment.Remove()
SectionCollection Add(ISection), IndexOf(ISection) DocumentObject overloads
PermissionCollection FindById(string), this[string] FindById(int)/Remove(int)

Two more items: the old declaration is replaced by a same-named base-class member, but the signature changes

Type Old declaration Inherited from in the new version Change
DocPicture System.Single Rotation { get; set; } ShapeBase float → double; the old member hid the same-named base property
HeadersFooters override IEnumerator GetEnumerator() DocumentObjectCollection IEnumerator → IEnumerator<DocumentObject>

In the old version DocPicture.Rotation hid ShapeBase.Rotation (double) with a float member; the new version removes that hiding declaration, so DocPicture.Rotation now resolves to double. Source that depends on float needs an explicit cast, and old binaries fail because of the return-type mismatch.

In addition, the strongly typed Add/IndexOf/Insert/Remove of CellCollection/RowCollection are removed, but the base class DocumentObjectCollection still provides DocumentObject versions; the 11 collection capabilities of ShapeItemCollection, however, have no base-class fallback.

4.3 Accessor changes

Type Member 14.9.11 14.10.9 Compatibility
Bookmark Name get get/set Setter added; compatible
Field Separator get get/set Setter added; compatible
ShapeBase Size get get/set Setter added; compatible
Permission EditorGroup get get/set Setter added; compatible
Document TextBoxes get/set get Setter removed; breaking

The setter of Document.TextBoxes is removed: old code that replaces the whole text-box collection will no longer compile and should instead add/remove through DocumentObjectCollection/TextBoxCollection methods on the existing collection.

4.4 Obsolete markers (warning level)

The following 4 members gain [Obsolete] (IsError = false, warning only):

This reflects the API direction of the new version: adding/removing through the collection itself is gradually giving way to DOM tree operations on CompositeDocumentObject.

4.5 Behavioural/semantic changes

5. Compatibility Impact Analysis

5.1 Binary compatibility

Change CLR-level consequence Notes
Enum constant renumbering No exception, silent errors const values are inlined; old numbers mean something different in the new version
Type removal TypeLoadException / MissingMethodException Loading fails when a signature references the type
Base-class change InvalidCastException / MissingMethodException Inherited-member resolution and cast targets change
Return type change MissingMethodException The return type is part of the CLR signature
Parameter type change (string→int) MissingMethodException Signature mismatch
Add/Insert return int→void MissingMethodException Signature mismatch
Member moved up to a base class Usually resolves The CLR walks up the base-class chain
Member moved down to a derived class Very likely MissingMethodException Old IL references the original declaring type; no search in derived classes
New interface implementation Compatible Does not change existing member signatures
New setter Compatible New method
Removed setter MissingMethodException (set_*) Old IL fails when calling the setter
New Obsolete Compatible Compile warning only
Assembly version change Possible FileLoadException Strong-name binding needs a bindingRedirect

Conclusion: even if a bindingRedirect is configured so the assembly loads, the signature/inheritance changes above will still throw on first use; and the enum problem may not even throw, which is more harmful.

5.2 Source compatibility

5.3 Behavioural compatibility

Even after all source compiles, the following behaviours still need regression testing:

  1. Table layout, width, merging, splitting and XHTML insertion for SDT rows/cells.
  2. Matching of permission ranges (start/end/permission) and editor identities.
  3. Body structure of comments/footnotes, and the differences between CommentedItems and the old Items.
  4. The update behaviour of TOC now that it is a Field.
  5. Child content and text extraction for shapes/text boxes/pictures as IBody.
  6. Index, order, event/cache behaviour after collection Add.
  7. Enumeration and Count of the header/footer collection.
  8. DocumentObjectType branching during document traversal.

5.4 Compatibility matrix

Change Binary Source Behaviour Handling level
DocumentObjectType renumbering Silent errors OK after recompile High P0
Permission string→int Breaking Breaking High P0
SDT Row/Cell base-class change Breaking Breaking High P0
Type removals (9) Breaking Breaking High P0
DocumentObjectCollection restructuring Breaking Breaking Medium-high P0
19 base-class changes Breaking Breaking High P0
Return type changes (21 items) Breaking Breaking Medium P1
Add/Insert int→void Breaking Breaking Medium P1
Members moved down (ChildObjects etc.) Very likely breaking Cast required Medium P1
Members moved up (Shape properties etc.) Usually compatible Compatible Low P2
New setters/interfaces/types Compatible Compatible Low P2
Obsolete markers Compatible Warning Low P2

6. Migration Guide

6.1 Migration order (recommended)

Step Action Main checks
1 Recompile all projects referencing Spire.Doc uniformly Do not replace the DLL directly; update bindingRedirect to 14.10.9.0
2 Migrate persisted DocumentObjectType values Database, JSON, caches, config files; map by constant name
3 Permission string ID → int Data model, permission ranges, FindById/indexer/removal
4 Collection APIs Add return value, strongly typed overloads, base-class types, indexer return types
5 SDT code SDTContent/Body, table capabilities of Row/Cell, constructors
6 ChildObjects/GetIndex/ToString(separator) Cast to CompositeDocumentObject or switch to the new DOM API
7 IBody/IParagraphBase return types Explicit cast or switch to interfaces
8 Comment/Footnote CommentedItems, Footnote's own IBody, EnsureMinimum
9 Shapes/formulas ApplyCharacterFormat → CharacterFormat/ApplyStyle; Size setter
10 Regression testing SDT, permissions, tables, comments, footnotes, TOC, headers/footers, text boxes

6.2 Key code migrations

(1) Enum checks

// After recompiling, use constant names — not numbers
if (obj.DocumentObjectType == DocumentObjectType.Paragraph) { ... }

// If you need to migrate old persisted numbers to the new enum, map by old constant name first:
// old 4 (Paragraph) -> new Paragraph (5)
// old 0 (Document)  -> new Document (1)
// old 63 (Any)      -> no corresponding member in the new version

(2) ChildObjects / child nodes

// Old code: accessible from any DocumentObject
DocumentObjectCollection children = documentObject.ChildObjects;

// New code: only composite objects have ChildObjects
if (documentObject is CompositeDocumentObject composite)
{
    DocumentObjectCollection children = composite.ChildObjects;
    DocumentObject first = composite.FirstChild;
    int index = composite.GetIndex(child);
}

(3) Adding to collections

// Add no longer returns an index
body.ChildObjects.Add(paragraph);
int index = body.ChildObjects.IndexOf(paragraph);

// Strongly typed collection overloads are gone; use the DocumentObject overloads
row.Cells.Add((DocumentObject)cell);
table.Rows.Insert(0, (DocumentObject)row);

(4) Interface return types

// Old code
ParagraphBase item = doc.CreateParagraphItem(ParagraphItemType.TextRange);
Body body = comment.Body;

// New code
IParagraphBase item = doc.CreateParagraphItem(ParagraphItemType.TextRange);
IBody body = comment.Body;

// Cast explicitly when you need the concrete type
var paragraph = (Paragraph)item;

(5) Comment / Footnote

// Comment.Items has been removed
foreach (IParagraphBase item in comment.CommentedItems) { ... }

// Footnote.TextBody has been removed; Footnote is itself an IBody
footnote.AddParagraph();
IBody footnoteBody = footnote.Body;

(6) TextBodyPart / TextBodySelection

part.Copy((IParagraphBase)paragraphBase, true);
part.PasteAfter((IParagraphBase)paragraphBase);
var selection = new TextBodySelection((IParagraphBase)start, (IParagraphBase)end);

(7) Shape formatting

// Old code: ApplyCharacterFormat directly on the shape
shape.ApplyCharacterFormat(format);

// New code: shapes no longer inherit ParagraphBase; use the CharacterFormat property / ApplyStyle
shape.ApplyStyle("MyStyle");
// or copy item by item into shape.CharacterFormat

(8) IDocCloneable / ISectionCollection

// Namespace migration
using Spire.Doc.Interface; // was Spire.Doc.CompoundFile
IDocCloneable cloneable = obj;

// IWSectionCollection -> ISectionCollection (empty marker interface)
ISectionCollection sections = document.Sections;
Section first = (Section)sections; // the indexer returns IDocumentObject

(9) TextBoxCollection indexer

// Old code
TextBox textBox = document.TextBoxes;

// New code: the indexer returns ShapeObject
TextBox textBox = (TextBox)document.TextBoxes;

6.3 Items that cannot be migrated automatically / need manual design

  1. Persisted DocumentObjectType values: must be mapped semantically, not carried over numerically.
  2. Table capabilities of SDT Row/Cell: the new model no longer provides CellFormat, RowFormat, Cells, merging/splitting, etc.; redesign or find alternative APIs.
  3. Style.NameToBuiltIn: no equivalent replacement; maintain a name mapping table (built-in style names and enum names do not always match).
  4. ApplyCharacterFormat: no equivalent method on shapes/comments/footnotes etc.; copying CharacterFormat item by item may not fully reproduce the original behaviour.
  5. ToString(string separator): no direct replacement; walk the children and concatenate yourself.
  6. ShapeItemCollection: the public type still exists, but all collection operations are gone, and no public member returns this type; if you use it via reflection/internal paths, switch to another collection.
  7. Permission ID allocation: string → integer is a data-model change requiring a uniqueness and migration strategy.

7. Non-Breaking Enhancements (available for use)

7.1 DOM tree operations

DocumentObject gains GetText(), Remove(), GetAncestor(...), GetNextInPreOrder(...), GetPreviousInPreOrder(...), HasChildNodes; CompositeDocumentObject gains AppendChild, PrependChild, InsertBefore, InsertAfter, RemoveChild, RemoveAllChildren, RemoveChildRange, GetChild, GetChildNodes, an integer indexer, and ChildObjects/FirstChild/LastChild. This API group replaces part of the collection add/remove and manual traversal code.

7.2 Revision tracking

New IRevisionTracking (8 members), implemented by 35 types: IsInsertRevision, IsDeleteRevision, IsMoveFromRevision, IsMoveToRevision, InsertRevision, DeleteRevision, MoveFromRevision, MoveToRevision. Comments, footnotes, paragraphs, fields, shapes, watermarks etc. can all handle revisions uniformly.

7.3 Typed range collections

7.4 Collection and query enhancements

7.5 Writable properties and convenience members

8. Full Change List and Tool Artifacts

Artifact Path Notes
This report E:\packges\netdll\Spire.Doc_API_Diff_14.9.11_vs_14.10.6.md Detailed report in Chinese
Full CSV list E:\packges\netdll\api-diff-tools\out\api-changes.csv 552 change rows, with priority / action migration-priority columns, UTF-8 BOM
Old API JSON E:\packges\netdll\api-diff-tools\out\api-14.9.11.json 508 types / 5460 members
New API JSON E:\packges\netdll\api-diff-tools\out\api-14.10.9.json 507 types / 5527 members
Export script E:\packges\netdll\api-diff-tools\dump-api.ps1 Reflection-only export of the public API
Analysis scripts analyze.py, query.py, refine.py, report_data.py, build_report.py Diffing / querying / effective surface / report generation

CSV columns: change, priority, type, member_kind, member_name, category, action, old_signature, new_signature, details. change values: type_added, type_removed, type_modified, member_added, member_removed, member_modified. priority convention: P0 must fix (using the API causes a compile failure, runtime failure or silent error — 169 items), P1 recommended fix (compiles, but with obsolete warnings, named arguments, inheritance substitution or semantic risk — 64 items), P2 recompile only (new APIs or pure metadata changes — 319 items). action gives the recommended handling for each row.

9. Methodology and Validation

9.1 Export method

  1. Use Assembly.ReflectionOnlyLoadFrom to load the target DLL for reflection only, without executing its business code.
  2. Before GetTypes(), walk GetReferencedAssemblies() to preload dependencies; for dependencies present locally, fall back to ReflectionOnlyLoadFrom.
  3. Use BindingFlags.Public | DeclaredOnly to export only members declared by the type itself; only public constructors are taken for constructors.
  4. For nested types, require the entire DeclaringType chain to be public, so that public nested types inside internal types are not mistakenly counted as exported types (508 after the fix).
  5. Generate ECMA-334 XML documentation IDs (T:/M:/P:/F:/E:) and cross-validate against the official XML documentation.
  6. Compute the "effective member surface": merge members along the in-assembly base-class chain; constructors are not inherited; a member counts as "still accessible" only when the type itself or an ancestor still provides it with the same name and signature in the new version.

9.2 Validation

9.3 Limitations

Appendix A: Added Types (8)

Added type Kind Member count Base class/notes
Spire.Doc.Collections.CommentRangeCollection Class 8 Spire.Doc.OwnerHolder
Spire.Doc.Collections.TextRangeCollection Class 2 Spire.Doc.Collections.DocumentObjectCollection
Spire.Doc.Documents.ISectionCollection Interface 0 —
Spire.Doc.Documents.StructureDocumentTagMarkEnd Class 1 Spire.Doc.Fields.ParagraphBase
Spire.Doc.Documents.StructureDocumentTagMarkStart Class 1 Spire.Doc.Fields.ParagraphBase
Spire.Doc.Fields.InlineBody Class 16 Spire.Doc.CompositeDocumentObject
Spire.Doc.Formatting.Revisions.IRevisionTracking Interface 8 —
Spire.Doc.Interface.IDocCloneable Interface 1 —

A.1 Public members of the added types

Added type Kind Member
Spire.Doc.Collections.CommentRangeCollection method System.Boolean Contains(Spire.Doc.DocumentObject documentObject)
Spire.Doc.Collections.CommentRangeCollection method System.Boolean Contains(Spire.Doc.Interface.IDocumentObject documentObject)
Spire.Doc.Collections.CommentRangeCollection method override System.Collections.Generic.IEnumerator<Spire.Doc.Interface.IParagraphBase> GetEnumerator()
Spire.Doc.Collections.CommentRangeCollection method System.Int32 IndexOf(Spire.Doc.DocumentObject documentObject)
Spire.Doc.Collections.CommentRangeCollection method System.Int32 IndexOf(Spire.Doc.Interface.IDocumentObject documentObject)
Spire.Doc.Collections.CommentRangeCollection method Spire.Doc.Interface.IParagraphBase[] ToArray()
Spire.Doc.Collections.CommentRangeCollection property System.Int32 Count { get; }
Spire.Doc.Collections.CommentRangeCollection property Spire.Doc.Interface.IParagraphBase this[System.Int32 index] { get; }
Spire.Doc.Collections.TextRangeCollection method Spire.Doc.Interface.ITextRange[] ToArray()
Spire.Doc.Collections.TextRangeCollection property Spire.Doc.Interface.ITextRange this[System.Int32 index] { get; }
Spire.Doc.Documents.StructureDocumentTagMarkEnd property Spire.Doc.Documents.DocumentObjectType DocumentObjectType { get; }
Spire.Doc.Documents.StructureDocumentTagMarkStart property Spire.Doc.Documents.DocumentObjectType DocumentObjectType { get; }
Spire.Doc.Fields.InlineBody method Spire.Doc.Documents.Paragraph AddParagraph()
Spire.Doc.Fields.InlineBody method Spire.Doc.Table AddTable()
Spire.Doc.Fields.InlineBody method Spire.Doc.Table AddTable(System.Boolean showBorder)
Spire.Doc.Fields.InlineBody method override System.Void ApplyStyle(Spire.Doc.Documents.DefaultCharacterStyle bstyle)
Spire.Doc.Fields.InlineBody method override System.Void ApplyStyle(System.String styleName)
Spire.Doc.Fields.InlineBody property Spire.Doc.Formatting.CharacterFormat CharacterFormat { get; }
Spire.Doc.Fields.InlineBody property Spire.Doc.Formatting.Revisions.EditRevision DeleteRevision { get; set; }
Spire.Doc.Fields.InlineBody property Spire.Doc.Formatting.Revisions.EditRevision InsertRevision { get; set; }
Spire.Doc.Fields.InlineBody property System.Boolean IsDeleteRevision { get; }
Spire.Doc.Fields.InlineBody property System.Boolean IsInsertRevision { get; }
Spire.Doc.Fields.InlineBody property System.Boolean IsMoveFromRevision { get; }
Spire.Doc.Fields.InlineBody property System.Boolean IsMoveToRevision { get; }
Spire.Doc.Fields.InlineBody property Spire.Doc.Formatting.Revisions.MoveRevision MoveFromRevision { get; set; }
Spire.Doc.Fields.InlineBody property Spire.Doc.Formatting.Revisions.MoveRevision MoveToRevision { get; set; }
Spire.Doc.Fields.InlineBody property Spire.Doc.Documents.Paragraph OwnerParagraph { get; }
Spire.Doc.Fields.InlineBody property System.String StyleName { get; }
Spire.Doc.Formatting.Revisions.IRevisionTracking property Spire.Doc.Formatting.Revisions.EditRevision DeleteRevision { get; }
Spire.Doc.Formatting.Revisions.IRevisionTracking property Spire.Doc.Formatting.Revisions.EditRevision InsertRevision { get; }
Spire.Doc.Formatting.Revisions.IRevisionTracking property System.Boolean IsDeleteRevision { get; }
Spire.Doc.Formatting.Revisions.IRevisionTracking property System.Boolean IsInsertRevision { get; }
Spire.Doc.Formatting.Revisions.IRevisionTracking property System.Boolean IsMoveFromRevision { get; }
Spire.Doc.Formatting.Revisions.IRevisionTracking property System.Boolean IsMoveToRevision { get; }
Spire.Doc.Formatting.Revisions.IRevisionTracking property Spire.Doc.Formatting.Revisions.MoveRevision MoveFromRevision { get; }
Spire.Doc.Formatting.Revisions.IRevisionTracking property Spire.Doc.Formatting.Revisions.MoveRevision MoveToRevision { get; }
Spire.Doc.Interface.IDocCloneable method System.Object Clone()

Notes: CommentRangeCollection and TextRangeCollection are the new typed collections; InlineBody is the new base class of Comment/Footnote; IRevisionTracking is the revision-tracking interface; IDocCloneable migrated from the CompoundFile namespace; ISectionCollection is an empty marker interface; the two StructureDocumentTagMark* types are SDT boundary marks.

Appendix B: Removed Types (9)

Removed type Kind Member count Base class/notes
Spire.Doc.Collections.DocumentObjectCollection+ChangeItems Delegate 4 System.MulticastDelegate
Spire.Doc.Collections.DocumentObjectCollection+ChangeItemsType Enum 3 System.Enum
Spire.Doc.Collections.DocumentSubsetCollection Class 5 Spire.Doc.OwnerHolder
Spire.Doc.Collections.DocumentSubsetCollection+SubSetEnumerator Class 4 System.Object
Spire.Doc.CompoundFile.IDocCloneable Interface 1 —
Spire.Doc.Documents.IWSectionCollection Interface 3 —
Spire.Doc.Documents.SDTContent Class 1 Spire.Doc.Body
Spire.Doc.Documents.SDTInlineContent Class 5 Spire.Doc.DocumentObject
Spire.Doc.Interface.ITextBoxItemCollection Interface 2 —

Notes: DocumentSubsetCollection was the base class of the old ParagraphCollection/TableCollection; SDTContent/SDTInlineContent were SDT content wrappers; CompoundFile.IDocCloneable moved to Interface; IWSectionCollection is replaced by ISectionCollection; ITextBoxItemCollection had no public implementers; the two nested types were public artifacts of the old collection change notification.

Appendix C: Added Members (178)

C.1 Members on added types (37)

All 37 of these members are on the 8 types added in this version; the full list is in Appendix A.1 and is not repeated here.

C.2 Members added to existing types (141)

Type Kind Added member Obsolete
Spire.Doc.Body property Spire.Doc.Collections.BodyRegionCollection Items { get; } —
Spire.Doc.BookmarkStart property Spire.Doc.Bookmark Bookmark { get; } —
Spire.Doc.Bookmark method System.Void Remove() —
Spire.Doc.Bookmark property System.String Text { get; set; } —
Spire.Doc.Break property System.String Text { get; set; } —
Spire.Doc.Collections.BodyRegionCollection property Spire.Doc.BodyRegion this[System.Int32 index] { get; } —
Spire.Doc.Collections.BookmarkCollection method override System.Collections.IEnumerator GetEnumerator() —
Spire.Doc.Collections.BookmarkCollection method System.Void Remove(System.String bookmarkName) —
Spire.Doc.Collections.BookmarkCollection method System.Void ResetBookmarkCache() —
Spire.Doc.Collections.BookmarkCollection property System.Int32 Count { get; } —
Spire.Doc.Collections.CellCollection constructor CellCollection(Spire.Doc.CompositeDocumentObject container) —
Spire.Doc.Collections.CellCollection method Spire.Doc.TableCell[] ToArray() —
Spire.Doc.Collections.DocumentObjectCollection method System.Void Add(Spire.Doc.DocumentObject documentObject) —
Spire.Doc.Collections.DocumentObjectCollection method System.Boolean Contains(Spire.Doc.DocumentObject documentObject) —
Spire.Doc.Collections.DocumentObjectCollection method override System.Collections.Generic.IEnumerator<Spire.Doc.DocumentObject> GetEnumerator() —
Spire.Doc.Collections.DocumentObjectCollection method System.Int32 IndexOf(Spire.Doc.DocumentObject documentObject) —
Spire.Doc.Collections.DocumentObjectCollection method System.Void Insert(System.Int32 index, Spire.Doc.DocumentObject documentObject) This method is obsolete. Use Owner.InsertBefore(documentObject, refChild) or Owner.InsertAfter(documentObject, refChild) instead.
Spire.Doc.Collections.DocumentObjectCollection method System.Void Remove(Spire.Doc.DocumentObject documentObject) —
Spire.Doc.Collections.DocumentObjectCollection method Spire.Doc.DocumentObject[] ToArray() —
Spire.Doc.Collections.DocumentObjectCollection property System.Int32 Count { get; } —
Spire.Doc.Collections.FieldCollection method Spire.Doc.Fields.Field[] ToArray() —
Spire.Doc.Collections.FormFieldCollection method Spire.Doc.Fields.FormField[] ToArray() —
Spire.Doc.Collections.ParagraphCollection constructor ParagraphCollection(Spire.Doc.CompositeDocumentObject ownerBody) —
Spire.Doc.Collections.ParagraphCollection method Spire.Doc.Documents.Paragraph[] ToArray() —
Spire.Doc.Collections.ParagraphItemCollection method Spire.Doc.Interface.IParagraphBase[] ToArray() —
Spire.Doc.Collections.PermissionCollection method Spire.Doc.Permission FindById(System.Int32 id) —
Spire.Doc.Collections.PermissionCollection method override System.Collections.IEnumerator GetEnumerator() —
Spire.Doc.Collections.PermissionCollection method System.Void Remove(System.Int32 id) —
Spire.Doc.Collections.PermissionCollection property System.Int32 Count { get; } —
Spire.Doc.Collections.RowCollection constructor RowCollection(Spire.Doc.CompositeDocumentObject container) —
Spire.Doc.Collections.RowCollection method Spire.Doc.TableRow[] ToArray() —
Spire.Doc.Collections.SectionCollection method Spire.Doc.Section[] ToArray() —
Spire.Doc.Collections.StyleCollection method System.Int32 GetNextAvailableIstd() —
Spire.Doc.Collections.TableCollection constructor TableCollection(Spire.Doc.CompositeDocumentObject container) —
Spire.Doc.Collections.TableCollection method Spire.Doc.Table[] ToArray() —
Spire.Doc.Collections.TextBoxCollection method Spire.Doc.Fields.ShapeObject[] ToArray() —
Spire.Doc.CompositeDocumentObject method Spire.Doc.DocumentObject AppendChild(Spire.Doc.DocumentObject newChild) —
Spire.Doc.CompositeDocumentObject method Spire.Doc.DocumentObject GetChild(Spire.Doc.Documents.DocumentObjectType documentObjectType, System.Int32 index, System.Boolean isDeep) —
Spire.Doc.CompositeDocumentObject method Spire.Doc.Collections.DocumentObjectCollection GetChildNodes(Spire.Doc.Documents.DocumentObjectType documentObjectType, System.Boolean isDeep) —
Spire.Doc.CompositeDocumentObject method Spire.Doc.Collections.DocumentObjectCollection GetChildNodes(Spire.Doc.Documents.DocumentObjectType[] documentObjectTypes, System.Boolean isDeep) —
Spire.Doc.CompositeDocumentObject method override System.Collections.Generic.IEnumerator<Spire.Doc.DocumentObject> GetEnumerator() —
Spire.Doc.CompositeDocumentObject method Spire.Doc.DocumentObject InsertAfter(Spire.Doc.DocumentObject newChild, Spire.Doc.DocumentObject refChild) —
Spire.Doc.CompositeDocumentObject method Spire.Doc.DocumentObject InsertBefore(Spire.Doc.DocumentObject newChild, Spire.Doc.DocumentObject refChild) —
Spire.Doc.CompositeDocumentObject method Spire.Doc.DocumentObject PrependChild(Spire.Doc.DocumentObject newChild) —
Spire.Doc.CompositeDocumentObject method System.Void RemoveAllChildren() —
Spire.Doc.CompositeDocumentObject method Spire.Doc.DocumentObject RemoveChild(Spire.Doc.DocumentObject oldChild) —
Spire.Doc.CompositeDocumentObject method System.Void RemoveChildRange(Spire.Doc.DocumentObject startNode, Spire.Doc.DocumentObject endNode) —
Spire.Doc.CompositeDocumentObject property Spire.Doc.Collections.DocumentObjectCollection ChildObjects { get; } —
Spire.Doc.CompositeDocumentObject property Spire.Doc.DocumentObject FirstChild { get; } —
Spire.Doc.CompositeDocumentObject property System.Boolean HasChildNodes { get; } —
Spire.Doc.CompositeDocumentObject property Spire.Doc.DocumentObject this[System.Int32 index] { get; } —
Spire.Doc.CompositeDocumentObject property Spire.Doc.DocumentObject LastChild { get; } —
Spire.Doc.DocumentObject method virtual Spire.Doc.CompositeDocumentObject GetAncestor(Spire.Doc.Documents.DocumentObjectType ancestorType) —
Spire.Doc.DocumentObject method virtual Spire.Doc.CompositeDocumentObject GetAncestor(System.Type ancestorType) —
Spire.Doc.DocumentObject method Spire.Doc.DocumentObject GetNextInPreOrder(Spire.Doc.DocumentObject rootObject) —
Spire.Doc.DocumentObject method Spire.Doc.DocumentObject GetPreviousInPreOrder(Spire.Doc.DocumentObject rootObject) —
Spire.Doc.DocumentObject method System.String GetText() —
Spire.Doc.DocumentObject method System.Void Remove() —
Spire.Doc.DocumentObject property System.Boolean HasChildNodes { get; } —
Spire.Doc.Documents.DocumentNavigator method Spire.Doc.Fields.DropDownFormField InsertDropDown(System.String name, System.String[] items, System.Int32 selectedIndex) —
Spire.Doc.Documents.DocumentNavigator method System.Void MoveToBodyEnd() —
Spire.Doc.Documents.DocumentNavigator method System.Void MoveToBodyStart() —
Spire.Doc.Documents.DocumentNavigator method System.Boolean MoveToBookmark(System.String bookmarkName) —
Spire.Doc.Documents.DocumentNavigator method System.Boolean MoveToBookmark(System.String bookmarkName, System.Boolean isStart, System.Boolean isAfter) —
Spire.Doc.Documents.DocumentObjectType field const Spire.Doc.Documents.DocumentObjectType StructureDocumentTagMarkEnd = 8 —
Spire.Doc.Documents.DocumentObjectType field const Spire.Doc.Documents.DocumentObjectType StructureDocumentTagMarkStart = 7 —
Spire.Doc.Documents.Paragraph method Spire.Doc.PermissionEnd AppendPermEnd(System.Int32 id) —
Spire.Doc.Documents.Paragraph method Spire.Doc.PermissionStart AppendPermStart(System.Int32 id) —
Spire.Doc.Documents.Paragraph property Spire.Doc.Collections.TextRangeCollection TextNodes { get; } —
Spire.Doc.Documents.StructureDocumentTagCell constructor StructureDocumentTagCell(Spire.Doc.Document doc) —
Spire.Doc.Documents.StructureDocumentTagInline method override System.Void ApplyStyle(System.String styleName) —
Spire.Doc.Documents.StructureDocumentTagInline property Spire.Doc.Formatting.CharacterFormat CharacterFormat { get; } —
Spire.Doc.Documents.StructureDocumentTagInline property Spire.Doc.Formatting.Revisions.EditRevision DeleteRevision { get; set; } —
Spire.Doc.Documents.StructureDocumentTagInline property Spire.Doc.Formatting.Revisions.EditRevision InsertRevision { get; set; } —
Spire.Doc.Documents.StructureDocumentTagInline property System.Boolean IsDeleteRevision { get; } —
Spire.Doc.Documents.StructureDocumentTagInline property System.Boolean IsInsertRevision { get; } —
Spire.Doc.Documents.StructureDocumentTagInline property System.Boolean IsMoveFromRevision { get; } —
Spire.Doc.Documents.StructureDocumentTagInline property System.Boolean IsMoveToRevision { get; } —
Spire.Doc.Documents.StructureDocumentTagInline property Spire.Doc.Collections.ParagraphItemCollection Items { get; } —
Spire.Doc.Documents.StructureDocumentTagInline property Spire.Doc.Formatting.Revisions.MoveRevision MoveFromRevision { get; set; } —
Spire.Doc.Documents.StructureDocumentTagInline property Spire.Doc.Formatting.Revisions.MoveRevision MoveToRevision { get; set; } —
Spire.Doc.Documents.StructureDocumentTagInline property Spire.Doc.Documents.Paragraph OwnerParagraph { get; } —
Spire.Doc.Documents.StructureDocumentTagInline property System.String StyleName { get; } —
Spire.Doc.Documents.StructureDocumentTagInline property System.String Text { get; } —
Spire.Doc.Documents.StructureDocumentTagInline property Spire.Doc.Collections.TextRangeCollection TextNodes { get; } —
Spire.Doc.Documents.StructureDocumentTagRow constructor StructureDocumentTagRow(Spire.Doc.Document doc) —
Spire.Doc.Documents.StructureDocumentTag property Spire.Doc.Interface.IBody Body { get; } —
Spire.Doc.Documents.TextBodyPart method System.Void Copy(Spire.Doc.Interface.IParagraphBase pItem, System.Boolean clone) —
Spire.Doc.Documents.TextBodyPart method System.Void PasteAfter(Spire.Doc.Interface.IParagraphBase paragraphItem) —
Spire.Doc.Documents.TextBodySelection constructor TextBodySelection(Spire.Doc.Interface.IParagraphBase itemStart, Spire.Doc.Interface.IParagraphBase itemEnd) —
Spire.Doc.Fields.Comment property Spire.Doc.Collections.CommentRangeCollection CommentedItems { get; } —
Spire.Doc.Fields.DocPicture property System.Drawing.SizeF Size { get; set; } —
Spire.Doc.Fields.OMath.OfficeMath method override System.Void ApplyStyle(Spire.Doc.Documents.DefaultCharacterStyle bstyle) —
Spire.Doc.Fields.OMath.OfficeMath method override System.Void ApplyStyle(System.String styleName) —
Spire.Doc.Fields.OMath.OfficeMath property Spire.Doc.Formatting.CharacterFormat CharacterFormat { get; } —
Spire.Doc.Fields.OMath.OfficeMath property Spire.Doc.Formatting.Revisions.EditRevision DeleteRevision { get; set; } —
Spire.Doc.Fields.OMath.OfficeMath property Spire.Doc.Formatting.Revisions.EditRevision InsertRevision { get; set; } —
Spire.Doc.Fields.OMath.OfficeMath property System.Boolean IsDeleteRevision { get; } —
Spire.Doc.Fields.OMath.OfficeMath property System.Boolean IsInsertRevision { get; } —
Spire.Doc.Fields.OMath.OfficeMath property System.Boolean IsMoveFromRevision { get; } —
Spire.Doc.Fields.OMath.OfficeMath property System.Boolean IsMoveToRevision { get; } —
Spire.Doc.Fields.OMath.OfficeMath property Spire.Doc.Formatting.Revisions.MoveRevision MoveFromRevision { get; set; } —
Spire.Doc.Fields.OMath.OfficeMath property Spire.Doc.Formatting.Revisions.MoveRevision MoveToRevision { get; set; } —
Spire.Doc.Fields.OMath.OfficeMath property Spire.Doc.Documents.Paragraph OwnerParagraph { get; } —
Spire.Doc.Fields.OMath.OfficeMath property System.String StyleName { get; } —
Spire.Doc.Fields.ParagraphBase method virtual Spire.Doc.CompositeDocumentObject GetAncestor(Spire.Doc.Documents.DocumentObjectType objectType) —
Spire.Doc.Fields.ParagraphBase property System.Boolean HasChildNodes { get; } —
Spire.Doc.Fields.Shapes.ShapeBase method override System.Void ApplyStyle(Spire.Doc.Documents.DefaultCharacterStyle bstyle) —
Spire.Doc.Fields.Shapes.ShapeBase method override System.Void ApplyStyle(System.String styleName) —
Spire.Doc.Fields.Shapes.ShapeBase property Spire.Doc.Formatting.CharacterFormat CharacterFormat { get; } —
Spire.Doc.Fields.Shapes.ShapeBase property Spire.Doc.Formatting.Revisions.EditRevision DeleteRevision { get; set; } —
Spire.Doc.Fields.Shapes.ShapeBase property Spire.Doc.Formatting.Revisions.EditRevision InsertRevision { get; set; } —
Spire.Doc.Fields.Shapes.ShapeBase property System.Boolean IsDeleteRevision { get; } —
Spire.Doc.Fields.Shapes.ShapeBase property System.Boolean IsInsertRevision { get; } —
Spire.Doc.Fields.Shapes.ShapeBase property System.Boolean IsMoveFromRevision { get; } —
Spire.Doc.Fields.Shapes.ShapeBase property System.Boolean IsMoveToRevision { get; } —
Spire.Doc.Fields.Shapes.ShapeBase property Spire.Doc.Formatting.Revisions.MoveRevision MoveFromRevision { get; set; } —
Spire.Doc.Fields.Shapes.ShapeBase property Spire.Doc.Formatting.Revisions.MoveRevision MoveToRevision { get; set; } —
Spire.Doc.Fields.Shapes.ShapeBase property Spire.Doc.Documents.Paragraph OwnerParagraph { get; } —
Spire.Doc.Fields.Shapes.ShapeBase property System.String StyleName { get; } —
Spire.Doc.Fields.Shapes.ShapeBase property System.String Title { get; set; } —
Spire.Doc.Fields.Shapes.Shape property System.Boolean ExtrusionEnabled { get; } —
Spire.Doc.Fields.Shapes.Shape property System.Boolean ShadowEnabled { get; } —
Spire.Doc.Fields.Shapes.Shape property System.Drawing.Color StrokeColor { get; set; } —
Spire.Doc.Fields.Shapes.Shape property System.Double StrokeWeight { get; set; } —
Spire.Doc.Fields.Symbol property System.String Text { get; set; } —
Spire.Doc.HeadersFooters method Spire.Doc.HeaderFooter GetHeaderFooterByType(Spire.Doc.Documents.HeaderFooterType type) —
Spire.Doc.Interface.IBody method Spire.Doc.Table AddTable(System.Boolean showBorder) —
Spire.Doc.Interface.IBody property Spire.Doc.Interface.IParagraph FirstParagraph { get; } —
Spire.Doc.Interface.IBody property Spire.Doc.Collections.BodyRegionCollection Items { get; } —
Spire.Doc.Interface.IParagraphBase method System.Void ApplyStyle(Spire.Doc.Documents.DefaultCharacterStyle bstyle) —
Spire.Doc.Interface.IParagraphBase property Spire.Doc.Formatting.CharacterFormat CharacterFormat { get; } —
Spire.Doc.OwnerHolder method override System.Object Clone() —
Spire.Doc.PermissionEnd constructor PermissionEnd(Spire.Doc.Interface.IDocument document, System.Int32 id) —
Spire.Doc.PermissionEnd property Spire.Doc.PermissionStart PermissionStart { get; } —
Spire.Doc.PermissionStart constructor PermissionStart(Spire.Doc.Interface.IDocument doc, System.Int32 id) —
Spire.Doc.PermissionStart property Spire.Doc.Permission Permission { get; } —
Spire.Doc.Permission method System.Void Remove() —
Spire.Doc.Permission property System.String Editor { get; set; } —
Spire.Doc.TableRow property Spire.Doc.TableCell FirstCell { get; } —
Spire.Doc.TableRow property Spire.Doc.TableCell LastCell { get; } —

Appendix D: Directly Declared Removals (54 items)

These members were declared on the old type itself, and neither that type nor any ancestor provides them in the new version. Inherited members lost because of base-class changes are not in this table; see the effective member surface statistics.

Type Removed member Suggested replacement
Spire.Doc.Bookmark Bookmark(Spire.Doc.BookmarkStart start) Use Bookmark(BookmarkStart, BookmarkEnd), or BookmarkStart.Bookmark
Spire.Doc.Collections.BodyRegionCollection BodyRegionCollection(Spire.Doc.Body body) Usually obtained from Body.Items; do not new it yourself
Spire.Doc.Collections.CellCollection CellCollection(Spire.Doc.TableRow owner) Get it from TableRow.Cells, or use CellCollection(CompositeDocumentObject)
Spire.Doc.Collections.CellCollection System.Int32 Add(Spire.Doc.TableCell cell) Use the DocumentObject overload of the base class DocumentObjectCollection, with an explicit cast
Spire.Doc.Collections.CellCollection System.Int32 IndexOf(Spire.Doc.TableCell cell) Use the DocumentObject overload of the base class DocumentObjectCollection, with an explicit cast
Spire.Doc.Collections.CellCollection System.Void Insert(System.Int32 index, Spire.Doc.TableCell cell) Use the DocumentObject overload of the base class DocumentObjectCollection, with an explicit cast
Spire.Doc.Collections.CellCollection System.Void Remove(Spire.Doc.TableCell cell) Use the DocumentObject overload of the base class DocumentObjectCollection, with an explicit cast
Spire.Doc.Collections.CommentsCollection CommentsCollection(Spire.Doc.Document doc) Get it from Document.Comments
Spire.Doc.Collections.CommentsCollection System.Int32 Counts() Use Count
Spire.Doc.Collections.CommentsCollection System.Void Remove(Spire.Doc.Fields.Comment comment) Use Remove(DocumentObject) or comment.Remove()
Spire.Doc.Collections.ParagraphCollection ParagraphCollection(Spire.Doc.Collections.BodyRegionCollection bodyItems) Get it from Body.Paragraphs, or use ParagraphCollection(CompositeDocumentObject)
Spire.Doc.Collections.PermissionCollection Spire.Doc.Permission FindById(System.String id) Use FindById(int) / Remove(int)
Spire.Doc.Collections.PermissionCollection Spire.Doc.Permission this[System.String id] { get; } Use FindById(int) / Remove(int)
Spire.Doc.Collections.RowCollection RowCollection(Spire.Doc.Table owner) Get it from Table.Rows, or use RowCollection(CompositeDocumentObject)
Spire.Doc.Collections.RowCollection System.Int32 Add(Spire.Doc.TableRow row) Use the DocumentObject overload of the base class DocumentObjectCollection, with an explicit cast
Spire.Doc.Collections.RowCollection System.Int32 IndexOf(Spire.Doc.TableRow row) Use the DocumentObject overload of the base class DocumentObjectCollection, with an explicit cast
Spire.Doc.Collections.RowCollection System.Void Insert(System.Int32 index, Spire.Doc.TableRow row) Use the DocumentObject overload of the base class DocumentObjectCollection, with an explicit cast
Spire.Doc.Collections.RowCollection System.Void Remove(Spire.Doc.TableRow row) Use the DocumentObject overload of the base class DocumentObjectCollection, with an explicit cast
Spire.Doc.Collections.SectionCollection SectionCollection(Spire.Doc.Document doc) Get it from Document.Sections
Spire.Doc.Collections.SectionCollection override System.Int32 Add(Spire.Doc.Interface.ISection section) Use DocumentObjectCollection.Add/IndexOf(DocumentObject)
Spire.Doc.Collections.SectionCollection override System.Int32 IndexOf(Spire.Doc.Interface.ISection section) Use DocumentObjectCollection.Add/IndexOf(DocumentObject)
Spire.Doc.Collections.TableCollection TableCollection(Spire.Doc.Collections.BodyRegionCollection bodyItems) Get it from Body.Tables, or use TableCollection(CompositeDocumentObject)
Spire.Doc.DocumentObject Spire.Doc.Collections.DocumentObjectCollection ChildObjects { get; } Moved down to CompositeDocumentObject; cast before accessing
Spire.Doc.DocumentObject Spire.Doc.DocumentObject FirstChild { get; } Moved down to CompositeDocumentObject; cast before accessing
Spire.Doc.DocumentObject Spire.Doc.DocumentObject LastChild { get; } Moved down to CompositeDocumentObject; cast before accessing
Spire.Doc.DocumentObject virtual System.Int32 GetIndex(Spire.Doc.Interface.IDocumentObject entity) Moved down to CompositeDocumentObject; cast before accessing
Spire.Doc.DocumentObject virtual System.String ToString(System.String seperator) No direct replacement; walk the children and concatenate the text yourself (optionally with GetText())
Spire.Doc.Documents.DocumentObjectType const Spire.Doc.Documents.DocumentObjectType SDTBlockContent = 9 The SDT content concept has been removed; no direct replacement
Spire.Doc.Documents.DocumentObjectType const Spire.Doc.Documents.DocumentObjectType SDTCellContent = 12 The SDT content concept has been removed; no direct replacement
Spire.Doc.Documents.DocumentObjectType const Spire.Doc.Documents.DocumentObjectType SDTInlineContent = 10 The SDT content concept has been removed; no direct replacement
Spire.Doc.Documents.DocumentObjectType const Spire.Doc.Documents.DocumentObjectType SDTRowContent = 11 The SDT content concept has been removed; no direct replacement
Spire.Doc.Documents.Paragraph Spire.Doc.PermissionEnd AppendPermEnd(System.String id) Use AppendPermEnd(int id)
Spire.Doc.Documents.Paragraph Spire.Doc.PermissionStart AppendPermStart(System.String id) Use AppendPermStart(int id)
Spire.Doc.Documents.SDTProperties SDTProperties(Spire.Doc.DocumentObject owner) Get it from StructureDocumentTag.SDTProperties
Spire.Doc.Documents.StructureDocumentTag Spire.Doc.Documents.SDTContent SDTContent { get; } Use StructureDocumentTag.Body (IBody)
Spire.Doc.Documents.StructureDocumentTagCell StructureDocumentTagCell(Spire.Doc.TableRow ownerRow) An SDT Cell is no longer a TableCell; use the CompositeDocumentObject child-node API
Spire.Doc.Documents.StructureDocumentTagInline Spire.Doc.Documents.SDTInlineContent SDTContent { get; } Use Items / Text / TextNodes, or access through CompositeDocumentObject child nodes
Spire.Doc.Documents.StructureDocumentTagRow Spire.Doc.Collections.CellCollection Cells { get; } An SDT Row is no longer a TableRow; no direct replacement — use child nodes / the CompositeDocumentObject API
Spire.Doc.Documents.StructureDocumentTagRow Spire.Doc.Formatting.RowFormat RowFormat { get; } An SDT Row is no longer a TableRow; no direct replacement
Spire.Doc.Documents.StructureDocumentTagRow StructureDocumentTagRow(Spire.Doc.Table ownerTable) An SDT Row is no longer a TableRow; use the CompositeDocumentObject child-node API
Spire.Doc.Documents.Style static Spire.Doc.Documents.BuiltinStyle NameToBuiltIn(System.String styleName) No direct replacement; maintain a name-to-BuiltinStyle mapping, or use Enum.TryParse with name normalisation
Spire.Doc.Documents.TextBodyPart System.Void Copy(Spire.Doc.Fields.ParagraphBase pItem, System.Boolean clone) Use the Copy(IParagraphBase, bool) overload
Spire.Doc.Documents.TextBodyPart System.Void PasteAfter(Spire.Doc.Fields.ParagraphBase paragraphItem) Use the PasteAfter(IParagraphBase) overload
Spire.Doc.Documents.TextBodySelection TextBodySelection(Spire.Doc.Fields.ParagraphBase itemStart, Spire.Doc.Fields.ParagraphBase itemEnd) Use TextBodySelection(IParagraphBase, IParagraphBase)
Spire.Doc.Fields.Comment Spire.Doc.Collections.ParagraphItemCollection Items { get; } Use Comment.CommentedItems (CommentRangeCollection)
Spire.Doc.Fields.Comment System.Void EnsureMinimum() No direct replacement; add paragraphs/content as needed
Spire.Doc.Fields.Footnote Spire.Doc.Body TextBody { get; } Footnote is itself an IBody; call AddParagraph/AddTable etc. directly
Spire.Doc.Fields.Footnote System.Void EnsureMinimum() No direct replacement; add paragraphs/content as needed
Spire.Doc.Fields.OMath.OfficeMath Spire.Doc.Documents.Paragraph ParentParagraph { get; } Use OwnerParagraph
Spire.Doc.Fields.ParagraphBase Spire.Doc.Collections.DocumentObjectCollection ChildObjects { get; } Only accessible after a cast when the runtime object is a CompositeDocumentObject; for leaf nodes use HasChildNodes
Spire.Doc.Permission Permission(Spire.Doc.PermissionStart start) Use PermissionStart.Permission
Spire.Doc.Permission Permission(Spire.Doc.PermissionStart start, Spire.Doc.PermissionEnd end) Use PermissionStart.Permission; associate via PermissionEnd.PermissionStart
Spire.Doc.PermissionEnd PermissionEnd(Spire.Doc.Interface.IDocument document, System.String id) Use PermissionEnd(IDocument, int)
Spire.Doc.PermissionStart PermissionStart(Spire.Doc.Interface.IDocument doc, System.String id) Use PermissionStart(IDocument, int)

Appendix E: Removals Still Reachable by Inheritance (29 items)

These members were declared on some type in the old version; in the new version that type or an ancestor still provides a member with the same name and signature, so usually only a recompile is needed. However, DocPicture.Rotation and HeadersFooters.GetEnumerator changed signature and must not be treated as "fully compatible".

Type Old declared member Inherited from in the new version Notes
Spire.Doc.Body Spire.Doc.Collections.DocumentObjectCollection ChildObjects { get; } Spire.Doc.CompositeDocumentObject Signature unchanged; usually only a recompile is needed
Spire.Doc.Collections.CellCollection System.Void RemoveAt(System.Int32 index) Spire.Doc.Collections.DocumentObjectCollection Signature unchanged; usually only a recompile is needed
Spire.Doc.Collections.CommentsCollection System.Void Clear() Spire.Doc.Collections.DocumentObjectCollection Signature unchanged; usually only a recompile is needed
Spire.Doc.Collections.CommentsCollection System.Void RemoveAt(System.Int32 index) Spire.Doc.Collections.DocumentObjectCollection Signature unchanged; usually only a recompile is needed
Spire.Doc.Collections.ParagraphCollection override System.Void RemoveAt(System.Int32 index) Spire.Doc.Collections.DocumentObjectCollection Signature unchanged; usually only a recompile is needed
Spire.Doc.Collections.TableCollection System.Void RemoveAt(System.Int32 index) Spire.Doc.Collections.DocumentObjectCollection Signature unchanged; usually only a recompile is needed
Spire.Doc.Collections.TextBoxCollection System.Void Clear() Spire.Doc.Collections.DocumentObjectCollection Signature unchanged; usually only a recompile is needed
Spire.Doc.Collections.TextBoxCollection System.Void RemoveAt(System.Int32 index) Spire.Doc.Collections.DocumentObjectCollection Signature unchanged; usually only a recompile is needed
Spire.Doc.Document Spire.Doc.Collections.DocumentObjectCollection ChildObjects { get; } Spire.Doc.CompositeDocumentObject Signature unchanged; usually only a recompile is needed
Spire.Doc.Documents.Paragraph Spire.Doc.Collections.DocumentObjectCollection ChildObjects { get; } Spire.Doc.CompositeDocumentObject Signature unchanged; usually only a recompile is needed
Spire.Doc.Documents.StructureDocumentTag Spire.Doc.Collections.DocumentObjectCollection ChildObjects { get; } Spire.Doc.CompositeDocumentObject Signature unchanged; usually only a recompile is needed
Spire.Doc.Documents.StructureDocumentTagInline Spire.Doc.Collections.DocumentObjectCollection ChildObjects { get; } Spire.Doc.CompositeDocumentObject Signature unchanged; usually only a recompile is needed
Spire.Doc.Documents.StructureDocumentTagRow Spire.Doc.Collections.DocumentObjectCollection ChildObjects { get; } Spire.Doc.CompositeDocumentObject Signature unchanged; usually only a recompile is needed
Spire.Doc.Fields.Comment Spire.Doc.Collections.DocumentObjectCollection ChildObjects { get; } Spire.Doc.CompositeDocumentObject Signature unchanged; usually only a recompile is needed
Spire.Doc.Fields.DocPicture System.Single Rotation { get; set; } Spire.Doc.Fields.Shapes.ShapeBase Return type float→double; the old member hid the same-named base property and the new version inherits from ShapeBase — breaks both source and binary
Spire.Doc.Fields.Footnote Spire.Doc.Collections.DocumentObjectCollection ChildObjects { get; } Spire.Doc.CompositeDocumentObject Signature unchanged; usually only a recompile is needed
Spire.Doc.Fields.OMath.OfficeMath Spire.Doc.Collections.DocumentObjectCollection ChildObjects { get; } Spire.Doc.CompositeDocumentObject Signature unchanged; usually only a recompile is needed
Spire.Doc.Fields.ShapeObject Spire.Doc.Collections.DocumentObjectCollection ChildObjects { get; } Spire.Doc.CompositeDocumentObject Signature unchanged; usually only a recompile is needed
Spire.Doc.Fields.ShapeObject System.Boolean ExtrusionEnabled { get; } Spire.Doc.Fields.Shapes.Shape Signature unchanged; usually only a recompile is needed
Spire.Doc.Fields.ShapeObject System.Boolean ShadowEnabled { get; } Spire.Doc.Fields.Shapes.Shape Signature unchanged; usually only a recompile is needed
Spire.Doc.Fields.ShapeObject System.Double StrokeWeight { get; set; } Spire.Doc.Fields.Shapes.Shape Signature unchanged; usually only a recompile is needed
Spire.Doc.Fields.ShapeObject System.Drawing.Color StrokeColor { get; set; } Spire.Doc.Fields.Shapes.Shape Signature unchanged; usually only a recompile is needed
Spire.Doc.Fields.Shapes.ShapeBase Spire.Doc.Collections.DocumentObjectCollection ChildObjects { get; } Spire.Doc.CompositeDocumentObject Signature unchanged; usually only a recompile is needed
Spire.Doc.Fields.TextBox Spire.Doc.Collections.DocumentObjectCollection ChildObjects { get; } Spire.Doc.CompositeDocumentObject Signature unchanged; usually only a recompile is needed
Spire.Doc.HeadersFooters override System.Collections.IEnumerator GetEnumerator() Spire.Doc.Collections.DocumentObjectCollection Return type changes from IEnumerator to IEnumerator<DocumentObject>; assignable in source, but the binary signature does not match
Spire.Doc.Pages.FixedLayoutSpan Spire.Doc.DocumentObject ParentNode { get; } Spire.Doc.Pages.LayoutElement Signature unchanged; usually only a recompile is needed
Spire.Doc.Section Spire.Doc.Collections.DocumentObjectCollection ChildObjects { get; } Spire.Doc.CompositeDocumentObject Signature unchanged; usually only a recompile is needed
Spire.Doc.Table Spire.Doc.Collections.DocumentObjectCollection ChildObjects { get; } Spire.Doc.CompositeDocumentObject Signature unchanged; usually only a recompile is needed
Spire.Doc.TableRow Spire.Doc.Collections.DocumentObjectCollection ChildObjects { get; } Spire.Doc.CompositeDocumentObject Signature unchanged; usually only a recompile is needed

Appendix F: Non-Enum Modifications (37 items)

Type Member Change
Spire.Doc.BodyRegion Spire.Doc.Interface.IBody OwnerTextBody { get; } Return type Spire.Doc.Body → Spire.Doc.Interface.IBody
Spire.Doc.Body override Spire.Doc.Table AddTable(System.Boolean showBorder) Modifiers [] → [override]
Spire.Doc.Bookmark Bookmark(Spire.Doc.BookmarkStart bookmarkStart, Spire.Doc.BookmarkEnd bookmarkEnd) Parameter names [start, end] → [bookmarkStart, bookmarkEnd]
Spire.Doc.Bookmark System.String Name { get; set; } Accessors get → get set
Spire.Doc.Collections.DocumentObjectCollection System.Void Add(Spire.Doc.Interface.IDocumentObject documentObject) Return type System.Int32 → System.Void; parameter names [entity] → [documentObject]
Spire.Doc.Collections.DocumentObjectCollection System.Boolean Contains(Spire.Doc.Interface.IDocumentObject documentObject) Parameter names [entity] → [documentObject]
Spire.Doc.Collections.DocumentObjectCollection System.Int32 IndexOf(Spire.Doc.Interface.IDocumentObject documentObject) Parameter names [entity] → [documentObject]
Spire.Doc.Collections.DocumentObjectCollection System.Void Insert(System.Int32 index, Spire.Doc.Interface.IDocumentObject documentObject) Parameter names [index, entity] → [index, documentObject]; new Obsolete (warning level)
Spire.Doc.Collections.DocumentObjectCollection System.Void Remove(Spire.Doc.Interface.IDocumentObject documentObject) Parameter names [entity] → [documentObject]
Spire.Doc.Collections.DocumentObjectCollection override System.Void RemoveAt(System.Int32 index) New Obsolete (warning level); modifiers [] → [override]
Spire.Doc.Collections.FormFieldCollection System.Boolean ContainsName(System.String formFieldName) Parameter names [itemName] → [formFieldName]
Spire.Doc.Collections.ParagraphCollection override System.Void Add(Spire.Doc.Interface.IParagraph paragraph) Return type System.Int32 → System.Void
Spire.Doc.Collections.ParagraphCollection override System.Void Insert(System.Int32 index, Spire.Doc.Interface.IParagraph paragraph) New Obsolete (warning level)
Spire.Doc.Collections.ParagraphItemCollection Spire.Doc.Interface.IParagraphBase this[System.Int32 index] { get; } Return type Spire.Doc.Fields.ParagraphBase → Spire.Doc.Interface.IParagraphBase
Spire.Doc.Collections.TableCollection override System.Void Add(Spire.Doc.Interface.ITable table) Return type System.Int32 → System.Void
Spire.Doc.Collections.TableCollection System.Void Insert(System.Int32 index, Spire.Doc.Interface.ITable table) Return type System.Int32 → System.Void; new Obsolete (warning level)
Spire.Doc.Collections.TextBoxCollection Spire.Doc.Fields.ShapeObject this[System.Int32 index] { get; } Return type Spire.Doc.Fields.TextBox → Spire.Doc.Fields.ShapeObject
Spire.Doc.CompositeDocumentObject override System.Int32 IndexOf(Spire.Doc.Interface.IDocumentObject child) Parameter names [docObject] → [child]
Spire.Doc.Documents.Paragraph Spire.Doc.Interface.IParagraphBase this[System.Int32 index] { get; } Return type Spire.Doc.Fields.ParagraphBase → Spire.Doc.Interface.IParagraphBase
Spire.Doc.Documents.TextBodySelection Spire.Doc.Interface.IBody TextBody { get; } Return type Spire.Doc.Body → Spire.Doc.Interface.IBody
Spire.Doc.Document Spire.Doc.Interface.IParagraphBase CreateParagraphItem(Spire.Doc.Documents.ParagraphItemType itemType) Return type Spire.Doc.Fields.ParagraphBase → Spire.Doc.Interface.IParagraphBase
Spire.Doc.Document Spire.Doc.Collections.TextBoxCollection TextBoxes { get; } Accessors get set → get
Spire.Doc.Fields.Comment Spire.Doc.Interface.IBody Body { get; } Return type Spire.Doc.Body → Spire.Doc.Interface.IBody
Spire.Doc.Fields.Field Spire.Doc.Fields.FieldMark Separator { get; set; } Accessors get → get set
Spire.Doc.Fields.Footnote Spire.Doc.Interface.IBody Body { get; } Return type Spire.Doc.Body → Spire.Doc.Interface.IBody
Spire.Doc.Fields.ParagraphBase override System.Void ApplyStyle(Spire.Doc.Documents.DefaultCharacterStyle bstyle) Modifiers [] → [override]
Spire.Doc.Fields.Shapes.ShapeBase System.Drawing.SizeF Size { get; set; } Accessors get → get set
Spire.Doc.Fields.TextBox Spire.Doc.Interface.IBody Body { get; } Return type Spire.Doc.Body → Spire.Doc.Interface.IBody
Spire.Doc.Interface.IParagraphCollection System.Void Add(Spire.Doc.Interface.IParagraph paragraph) Return type System.Int32 → System.Void
Spire.Doc.Interface.IParagraph Spire.Doc.Interface.IParagraphBase this[System.Int32 index] { get; } Return type Spire.Doc.Fields.ParagraphBase → Spire.Doc.Interface.IParagraphBase
Spire.Doc.Interface.ITableCollection System.Void Add(Spire.Doc.Interface.ITable table) Return type System.Int32 → System.Void
Spire.Doc.Interface.ITextBox Spire.Doc.Interface.IBody Body { get; } Return type Spire.Doc.Body → Spire.Doc.Interface.IBody
Spire.Doc.Pages.FixedLayoutColumn Spire.Doc.Interface.IBody Body { get; } Return type Spire.Doc.Body → Spire.Doc.Interface.IBody
Spire.Doc.PermissionEnd System.Int32 Id { get; } Return type System.String → System.Int32
Spire.Doc.PermissionStart System.Int32 Id { get; } Return type System.String → System.Int32
Spire.Doc.Permission Spire.Doc.Documents.EditingGroup EditorGroup { get; set; } Accessors get → get set
Spire.Doc.Permission System.Int32 Id { get; } Return type System.String → System.Int32

Appendix G: Base-Class Changes (19 items)

Type Old base class New base class
Spire.Doc.Collections.BookmarkCollection Spire.Doc.Collections.DocumentItemCollectionBase Spire.Doc.OwnerHolder
Spire.Doc.Collections.CommentsCollection Spire.Doc.Collections.DocumentItemCollectionBase Spire.Doc.Collections.DocumentObjectCollection
Spire.Doc.Collections.DocumentObjectCollection Spire.Doc.Collections.DocumentItemCollectionBase Spire.Doc.OwnerHolder
Spire.Doc.Collections.FieldCollection Spire.Doc.Collections.DocumentItemCollectionBase Spire.Doc.Collections.DocumentObjectCollection
Spire.Doc.Collections.FormFieldCollection Spire.Doc.Collections.DocumentItemCollectionBase Spire.Doc.Collections.DocumentObjectCollection
Spire.Doc.Collections.ParagraphCollection Spire.Doc.Collections.DocumentSubsetCollection Spire.Doc.Collections.DocumentObjectCollection
Spire.Doc.Collections.PermissionCollection Spire.Doc.Collections.DocumentItemCollectionBase Spire.Doc.OwnerHolder
Spire.Doc.Collections.ShapeItemCollection Spire.Doc.Collections.DocumentObjectCollection Spire.Doc.Collections.DocumentItemCollectionBase
Spire.Doc.Collections.TableCollection Spire.Doc.Collections.DocumentSubsetCollection Spire.Doc.Collections.DocumentObjectCollection
Spire.Doc.Collections.TextBoxCollection Spire.Doc.Collections.DocumentItemCollectionBase Spire.Doc.Collections.DocumentObjectCollection
Spire.Doc.Documents.StructureDocumentTagCell Spire.Doc.TableCell Spire.Doc.CompositeDocumentObject
Spire.Doc.Documents.StructureDocumentTagInline Spire.Doc.Fields.ParagraphBase Spire.Doc.CompositeDocumentObject
Spire.Doc.Documents.StructureDocumentTagRow Spire.Doc.TableRow Spire.Doc.CompositeDocumentObject
Spire.Doc.Fields.Comment Spire.Doc.Fields.ParagraphBase Spire.Doc.Fields.InlineBody
Spire.Doc.Fields.Footnote Spire.Doc.Fields.ParagraphBase Spire.Doc.Fields.InlineBody
Spire.Doc.Fields.OMath.OfficeMath Spire.Doc.Fields.ParagraphBase Spire.Doc.CompositeDocumentObject
Spire.Doc.Fields.Shapes.ShapeBase Spire.Doc.Fields.ParagraphBase Spire.Doc.CompositeDocumentObject
Spire.Doc.Fields.TableOfContent Spire.Doc.Fields.ParagraphBase Spire.Doc.Fields.Field
Spire.Doc.HeadersFooters Spire.Doc.OwnerHolder Spire.Doc.Collections.DocumentObjectCollection

Appendix H: Summary of Type Metadata Interface Changes

114 types have metadata changes. The main additions/removals at the public interface level:

Interface Number of types newly implementing Notes
Spire.Doc.Interface.IDocCloneable 114 New implementation
System.Collections.Generic.IEnumerable<Spire.Doc.DocumentObject> 37 New implementation
Spire.Doc.Formatting.Revisions.IRevisionTracking 35 New implementation
Spire.Doc.Interface.ICollectionBase 29 New implementation
Spire.Doc.Interface.IDocumentObjectCollection 29 New implementation
System.Collections.IEnumerable 24 New implementation
Spire.Doc.Interface.IBody 7 New implementation
Spire.Doc.Interface.ITextRange 3 New implementation
Spire.Doc.Documents.ISectionCollection 1 New implementation
Spire.Doc.Interface.IField 1 New implementation
Interface Number of types losing implementation Notes
Spire.Doc.Documents.IWSectionCollection 1 Implementation lost
Spire.Doc.Interface.IDocumentObjectCollection 1 Implementation lost
Spire.Doc.Interface.ICollectionBase 1 Implementation lost
Spire.Doc.Interface.IBody 1 Implementation lost

Among these, Spire.Doc.Interface.IDocCloneable is newly implemented by 114 types; IRevisionTracking is newly implemented by 35 types; IBody gains 7 new implementations (StructureDocumentTag, Comment, Footnote, DocOleObject, DocPicture, ShapeObject, TextBox), and StructureDocumentTagCell loses IBody; ITextRange gains 3 new implementations (Break, Symbol, TableOfContent), and IField gains 1 new implementation (TableOfContent).

Non-public/obfuscated interfaces (spr...) are not counted in this table; the full raw interface list is in the JSON artifacts.

Appendix I: Effective Member Surface Lost by Type (Top 20)

Type Slots lost
Spire.Doc.Documents.StructureDocumentTagCell 27
Spire.Doc.Collections.ShapeItemCollection 11
Spire.Doc.Documents.StructureDocumentTagRow 11
Spire.Doc.PermissionEnd 6
Spire.Doc.PermissionStart 6
Spire.Doc.BookmarkEnd 5
Spire.Doc.BookmarkStart 5
Spire.Doc.Break 5
Spire.Doc.Collections.CellCollection 5
Spire.Doc.Collections.RowCollection 5
Spire.Doc.DocumentObject 5
Spire.Doc.Documents.CommentMark 5
Spire.Doc.Fields.CheckBoxFormField 5
Spire.Doc.Fields.ControlField 5
Spire.Doc.Fields.DropDownFormField 5
Spire.Doc.Fields.Field 5
Spire.Doc.Fields.FieldMark 5
Spire.Doc.Fields.FormField 5
Spire.Doc.Fields.IfField 5
Spire.Doc.Fields.MergeField 5