AyCode.Core/AyCode.Core/Serializers/PropertyAccessorBase.cs

84 lines
2.5 KiB
C#

using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
using static AyCode.Core.Helpers.JsonUtilities;
namespace AyCode.Core.Serializers;
/// <summary>
/// Base class for property accessors used by all serializers.
/// Contains common property metadata and getter functionality.
/// </summary>
public abstract class PropertyAccessorBase
{
/// <summary>
/// Property name.
/// </summary>
public string Name { get; }
/// <summary>
/// Pre-encoded UTF8 bytes of property name for fast matching.
/// </summary>
public byte[] NameUtf8 { get; }
/// <summary>
/// The property type (may be nullable).
/// </summary>
public Type PropertyType { get; }
/// <summary>
/// The underlying type (unwrapped from Nullable if applicable).
/// </summary>
public Type UnderlyingType { get; }
/// <summary>
/// Cached TypeCode for fast primitive type dispatch.
/// </summary>
public TypeCode PropertyTypeCode { get; }
/// <summary>
/// Whether the property type is nullable.
/// </summary>
public bool IsNullable { get; }
/// <summary>
/// The declaring type of this property.
/// </summary>
public Type DeclaringType { get; }
/// <summary>
/// True if this property needs recursive scanning (not primitive/string).
/// Pre-computed to avoid IsPrimitiveOrStringFast() calls in hot path.
/// </summary>
public bool IsComplexType { get; }
/// <summary>
/// Compiled getter delegate for reading property values.
/// </summary>
protected readonly Func<object, object?> _getter;
protected PropertyAccessorBase(PropertyInfo prop, Type declaringType)
{
Name = prop.Name;
NameUtf8 = Encoding.UTF8.GetBytes(prop.Name);
DeclaringType = declaringType;
PropertyType = prop.PropertyType;
var underlying = Nullable.GetUnderlyingType(PropertyType);
IsNullable = underlying != null;
UnderlyingType = underlying ?? PropertyType;
PropertyTypeCode = Type.GetTypeCode(UnderlyingType);
// Pre-compute: is this a complex type that needs recursive handling?
IsComplexType = !IsPrimitiveOrStringFast(PropertyType);
_getter = AcSerializerCommon.CreateCompiledGetter(declaringType, prop);
}
/// <summary>
/// Gets the property value from the target object.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public object? GetValue(object obj) => _getter(obj);
}