diff --git a/.claude/settings.local.json b/.claude/settings.local.json
index ec449c7..2511057 100644
--- a/.claude/settings.local.json
+++ b/.claude/settings.local.json
@@ -27,7 +27,8 @@
"Bash(cmd /c \"dir /B /O-D H:\\Applications\\Aycode\\Source\\AyCode.Core\\Test_Benchmark_Results\\Benchmark\\*.log 2>nul | head -1\")",
"Bash(timeout 30 dotnet run:*)",
"Bash(dotnet exec vstest:*)",
- "Bash(dotnet new:*)"
+ "Bash(dotnet new:*)",
+ "Bash(Remove-Item \"H:\\\\Applications\\\\Aycode\\\\Source\\\\AyCode.Core\\\\AyCode.Core\\\\Serializers\\\\Toons\\\\AcToonSerializer.RelationshipDetection.cs\")"
]
}
}
diff --git a/AyCode.Core/Helpers/JsonUtilities.cs b/AyCode.Core/Helpers/JsonUtilities.cs
index 33c164e..fe8fba5 100644
--- a/AyCode.Core/Helpers/JsonUtilities.cs
+++ b/AyCode.Core/Helpers/JsonUtilities.cs
@@ -525,6 +525,37 @@ public static class JsonUtilities
Attribute.IsDefined(p, typeof(System.Text.Json.Serialization.JsonIgnoreAttribute)));
}
+ ///
+ /// Checks if property has ToonIgnore attribute.
+ ///
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static bool HasToonIgnoreAttribute(PropertyInfo prop)
+ {
+ //return JsonIgnoreCache.GetOrAdd(prop, static p => Attribute.IsDefined(p, typeof(ToonIgnoreAttribute)));
+
+ return JsonIgnoreCache.GetOrAdd(prop, static p =>
+ Attribute.IsDefined(p, typeof(JsonIgnoreAttribute)) ||
+ Attribute.IsDefined(p, typeof(System.Text.Json.Serialization.JsonIgnoreAttribute)));
+ }
+
+ ///
+ /// Check if a property type is unsupported for serialization.
+ ///
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static bool IsUnsupportedPropertyType(Type type)
+ {
+ if (type.IsByRef || type.IsByRefLike)
+ return true;
+
+ if (type.IsPointer)
+ return true;
+
+ if (typeof(Type).IsAssignableFrom(type) || typeof(MemberInfo).IsAssignableFrom(type))
+ return true;
+
+ return false;
+ }
+
///
/// Checks if collection contains primitive elements.
///
diff --git a/AyCode.Core/Serializers/Binaries/AcBinaryDeserializer.BinaryDeserializeTypeMetadata.cs b/AyCode.Core/Serializers/Binaries/AcBinaryDeserializer.BinaryDeserializeTypeMetadata.cs
index cd923c4..33d7cc2 100644
--- a/AyCode.Core/Serializers/Binaries/AcBinaryDeserializer.BinaryDeserializeTypeMetadata.cs
+++ b/AyCode.Core/Serializers/Binaries/AcBinaryDeserializer.BinaryDeserializeTypeMetadata.cs
@@ -1,8 +1,9 @@
using System.Reflection;
using System.Runtime.CompilerServices;
+using AyCode.Core.Helpers;
using AyCode.Core.Serializers;
using AyCode.Core.Serializers.Attributes;
-
+using static AyCode.Core.Helpers.JsonUtilities;
namespace AyCode.Core.Serializers.Binaries;
public static partial class AcBinaryDeserializer
@@ -28,9 +29,9 @@ public static partial class AcBinaryDeserializer
///
public Type? GeneratedSerializerType { get; }
- public BinaryDeserializeTypeMetadata(Type type) : base(type)
+ public BinaryDeserializeTypeMetadata(Type type) : base(type, HasJsonIgnoreAttribute)
{
- var orderedProperties = GetSerializableProperties(type, requiresRead: true, requiresWrite: true);
+ var orderedProperties = GetSerializableProperties(type, requiresWrite: true);
PropertiesArray = new BinaryPropertySetterInfo[orderedProperties.Length];
for (var i = 0; i < orderedProperties.Length; i++)
diff --git a/AyCode.Core/Serializers/Binaries/AcBinaryDeserializer.CrossType.cs b/AyCode.Core/Serializers/Binaries/AcBinaryDeserializer.CrossType.cs
index 06d72c3..3069eec 100644
--- a/AyCode.Core/Serializers/Binaries/AcBinaryDeserializer.CrossType.cs
+++ b/AyCode.Core/Serializers/Binaries/AcBinaryDeserializer.CrossType.cs
@@ -11,10 +11,12 @@ public static partial class AcBinaryDeserializer
///
/// Helper to get index mapping for cross-type operations.
+ /// Uses cached PropertyInfo arrays from TypeMetadataBase.GetSerializableProperties.
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static int[] GetIndexMapping(Type sourceType, Type destType, PropertyMapperDelegate? customMapper)
- => IndexMappingCache.GetOrBuild(sourceType, destType, customMapper, DeserializeCrossTypeBase.GetOrderedProperties);
+ => IndexMappingCache.GetOrBuild(sourceType, destType, customMapper,
+ type => GetTypeMetadata(type).GetSerializableProperties(type, requiresWrite: true));
#region Cross-Type Deserialization
diff --git a/AyCode.Core/Serializers/Binaries/AcBinarySerializer.BinaryTypeMetadata.cs b/AyCode.Core/Serializers/Binaries/AcBinarySerializer.BinaryTypeMetadata.cs
index 31999b6..b59c323 100644
--- a/AyCode.Core/Serializers/Binaries/AcBinarySerializer.BinaryTypeMetadata.cs
+++ b/AyCode.Core/Serializers/Binaries/AcBinarySerializer.BinaryTypeMetadata.cs
@@ -23,9 +23,9 @@ public static partial class AcBinarySerializer
///
public Type? GeneratedSerializerType { get; }
- public BinaryTypeMetadata(Type type) : base(type)
+ public BinaryTypeMetadata(Type type, Func ignorePropertyFilter) : base(type,ignorePropertyFilter)
{
- var orderedProperties = GetSerializableProperties(type, requiresRead: true, requiresWrite: true);
+ var orderedProperties = GetSerializableProperties(type, requiresWrite: true);
Properties = new BinaryPropertyAccessor[orderedProperties.Length];
for (var i = 0; i < orderedProperties.Length; i++)
diff --git a/AyCode.Core/Serializers/Binaries/AcBinarySerializer.cs b/AyCode.Core/Serializers/Binaries/AcBinarySerializer.cs
index ab1a0a9..fca55f2 100644
--- a/AyCode.Core/Serializers/Binaries/AcBinarySerializer.cs
+++ b/AyCode.Core/Serializers/Binaries/AcBinarySerializer.cs
@@ -1,4 +1,6 @@
-using System.Buffers;
+using AyCode.Core.Helpers;
+using AyCode.Core.Serializers.Expressions;
+using System.Buffers;
using System.Collections;
using System.Collections.Concurrent;
using System.Linq.Expressions;
@@ -6,7 +8,6 @@ using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
-using AyCode.Core.Serializers.Expressions;
using static AyCode.Core.Helpers.JsonUtilities;
namespace AyCode.Core.Serializers.Binaries;
@@ -1239,7 +1240,7 @@ public static partial class AcBinarySerializer
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static BinaryTypeMetadata GetTypeMetadata(Type type)
- => BinaryTypeMetadata.GetOrCreateMetadata(type, static t => new BinaryTypeMetadata(t));
+ => BinaryTypeMetadata.GetOrCreateMetadata(type, static t => new BinaryTypeMetadata(t, HasJsonIgnoreAttribute));
// Type metadata helpers moved to AcBinarySerializer.BinaryTypeMetadata.cs
diff --git a/AyCode.Core/Serializers/DeserializeCrossTypeBase.cs b/AyCode.Core/Serializers/DeserializeCrossTypeBase.cs
index b1abb2b..88e9303 100644
--- a/AyCode.Core/Serializers/DeserializeCrossTypeBase.cs
+++ b/AyCode.Core/Serializers/DeserializeCrossTypeBase.cs
@@ -1,6 +1,5 @@
-using System.Reflection;
+using AyCode.Core.Helpers;
using AyCode.Core.Serializers.Jsons;
-using static AyCode.Core.Serializers.TypeMetadataBase;
namespace AyCode.Core.Serializers;
@@ -8,14 +7,10 @@ namespace AyCode.Core.Serializers;
/// Utility class providing common cross-type deserialization functionality.
/// Shared by both JSON and Binary deserializers.
///
-public static class DeserializeCrossTypeBase
+public class DeserializeCrossTypeBase : TypeMetadataBase
{
- ///
- /// Gets ordered properties for a type using stable PropertyIndex ordering.
- /// Wrapper around TypeMetadataBase.GetSerializableProperties for consistency.
- ///
- public static PropertyInfo[] GetOrderedProperties(Type type)
- => GetSerializableProperties(type, requiresRead: true, requiresWrite: true);
+ protected DeserializeCrossTypeBase(Type type) : base(type, JsonUtilities.HasJsonIgnoreAttribute)
+ {}
///
/// Checks if two types are the same (fast path detection).
diff --git a/AyCode.Core/Serializers/DeserializeTypeMetadataBase.cs b/AyCode.Core/Serializers/DeserializeTypeMetadataBase.cs
index 6cb9e8f..401a8f1 100644
--- a/AyCode.Core/Serializers/DeserializeTypeMetadataBase.cs
+++ b/AyCode.Core/Serializers/DeserializeTypeMetadataBase.cs
@@ -29,7 +29,7 @@ public abstract class DeserializeTypeMetadataBase : TypeMetadataBase<
///
public Func