How to Fill Polymorphic Data
This page covers: when a field type is an abstract bean (with multiple subclasses), how to indicate which concrete subtype a cell is.
In one sentence
Write the concrete type name (or alias) first, then fill data in that subclass’s field order.
Schema example
<bean name="Shape"/>
<bean name="Circle" parent="Shape">
<var name="radius" type="float"/>
</bean>
<bean name="Rect" parent="Shape" alias="矩形">
<var name="width" type="float"/>
<var name="height" type="float"/>
</bean>
<bean name="Spawn">
<var name="id" type="int"/>
<var name="shape" type="Shape"/>
</bean>
Shape is the abstract base class; Circle / Rect are instantiable subclasses.
Excel: fill across columns
shape spans multiple columns: merge shape on the first row; the child row writes $type and each subclass field.
| ##var | id | shape | |||
|---|---|---|---|---|---|
| ##var | $type | radius | width | height | |
| ##type | int | string | float | float | float |
| 1 | Circle | 1.5 | |||
| 2 | Rect | 2 | 3 | ||
| 3 | 矩形 | 4 | 5 | ||
Notes:
- The
$typecolumn (or the first value in the merged range) holdsCircle/Rect/ alias矩形. - Leave unrelated field columns empty.
- Without a
$typecolumn name, the convention is still “first cell in the range = type name”.
Excel: one cell (sep / lite)
When the field name or type carries sep / format, you can write it in one cell:
| ##var | id | shape#sep=, |
|---|---|---|
| ##type | int | Shape |
| 1 | Circle,1.5 | |
| 2 | Rect,2,3 |
Or shape#format=lite:
| ##var | id | shape#format=lite |
|---|---|---|
| ##type | int | Shape |
| 1 | {Circle,1.5} | |
| 2 | {Rect,2,3} |
See more in sep and Compact format.
Nullable polymorphism Shape?
| Cell | Meaning |
|---|---|
null or leave empty per rules | Empty |
Circle,1.5 / {Circle,1.5} | Non-null Circle |
Other data sources
| Format | Type-field example |
|---|---|
| json / yaml | "shape": { "$type": "Circle", "radius": 1.5 } |
| lua | shape = { _type_ = "Circle", radius = 1.5 } |
| xml | <shape type="Circle"><radius>1.5</radius></shape> |
Runtime (C# sketch)
Shape s = row.Shape;
if (s is Circle c) { /* c.Radius */ }
else if (s is Rect r) { /* r.Width, r.Height */ }
Common pitfalls
- Writing the abstract class name
Shapeinstead of a subclass name. - Typo in type name / alias.
- Subclass field order does not match Schema (column mode follows declaration order).
- Forgot
parentin Schema, so the generated side has no polymorphism.