Deduplicate property overrides; Shipping carrier nullable
- Fix property enumeration to dedupe overridden/shadowed properties, ensuring only the most-derived is included (affects serialization and schema). - Update TOON_ISSUES.md: close duplicate property issue, document root cause and resolution. - Make CargoPartnerId nullable in Shipping and IShipping; clarify ToonDescription for carrier/truck/trailer fields. - Refine ShippingDocument ToonDescription for clarity. - Minor null-safety and style cleanup in GridShipping.razor.
This commit is contained in:
parent
5e06f3e122
commit
d8a577024a
|
|
@ -363,14 +363,21 @@ public abstract class TypeMetadataBase
|
||||||
[UnconditionalSuppressMessage("Trimming", "IL2080",
|
[UnconditionalSuppressMessage("Trimming", "IL2080",
|
||||||
Justification = "Same as IL2070 — currentType variable starts DAMs-annotated but loses annotation "
|
Justification = "Same as IL2070 — currentType variable starts DAMs-annotated but loses annotation "
|
||||||
+ "through the BaseType reassignment in the loop.")]
|
+ "through the BaseType reassignment in the loop.")]
|
||||||
private static List<PropertyInfo> BuildPropertyList(
|
private static List<PropertyInfo> BuildPropertyList([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)] Type type, bool requiresWrite)
|
||||||
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)] Type type,
|
|
||||||
bool requiresWrite)
|
|
||||||
{
|
{
|
||||||
// Collect properties from inheritance hierarchy (derived -> base order)
|
// Collect properties from inheritance hierarchy (derived -> base order)
|
||||||
// Sorted alphabetically for deterministic property index ordering
|
// Sorted alphabetically for deterministic property index ordering
|
||||||
var allProperties = new List<PropertyInfo>();
|
var allProperties = new List<PropertyInfo>();
|
||||||
|
|
||||||
|
// Dedup by name across inheritance levels. An overridden (or 'new'-shadowed) property is
|
||||||
|
// declared at EVERY level it appears in, so BindingFlags.DeclaredOnly returns it once per
|
||||||
|
// level — without this guard the derived AND base PropertyInfo would both be collected
|
||||||
|
// (duplicate wire field on the runtime path; duplicate @types entry in Toon). The derived->base
|
||||||
|
// walk means the most-derived declaration is seen first and wins. Mirrors the SGen path
|
||||||
|
// (AcBinarySourceGenerator.GetAllSerializablePropertySymbols) so the runtime and generated
|
||||||
|
// property orders stay bit-identical.
|
||||||
|
var seen = new HashSet<string>(StringComparer.Ordinal);
|
||||||
|
|
||||||
for (var currentType = type; currentType != null && currentType != typeof(object); currentType = currentType.BaseType)
|
for (var currentType = type; currentType != null && currentType != typeof(object); currentType = currentType.BaseType)
|
||||||
{
|
{
|
||||||
// Get properties declared at this level only
|
// Get properties declared at this level only
|
||||||
|
|
@ -379,7 +386,8 @@ public abstract class TypeMetadataBase
|
||||||
.Where(p => p.CanRead &&
|
.Where(p => p.CanRead &&
|
||||||
(!requiresWrite || p.CanWrite) &&
|
(!requiresWrite || p.CanWrite) &&
|
||||||
p.GetIndexParameters().Length == 0 &&
|
p.GetIndexParameters().Length == 0 &&
|
||||||
!IsUnsupportedPropertyType(p.PropertyType))
|
!IsUnsupportedPropertyType(p.PropertyType) &&
|
||||||
|
seen.Add(p.Name))
|
||||||
.OrderBy(static p => p.Name, StringComparer.Ordinal);
|
.OrderBy(static p => p.Name, StringComparer.Ordinal);
|
||||||
|
|
||||||
allProperties.AddRange(levelProperties);
|
allProperties.AddRange(levelProperties);
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue