Extending that thought a bit, from what I could determine Equals is a bit
nuanced as well. First argument x appears to be cached or disassembled,
whereas it would seem second argument y appears to be assembled version of
the same.
protected virtual bool Equals(P x, P y) => x is IEquatable<P> xe && y is
IEquatable<P> ye && xe.Equals(ye);
public new virtual bool Equals(object x, object y)
{
object Normalize(object value) => value switch
{
null => null,
R r => Disassemble(r),
P p => p,
_ => throw new InvalidOperationException($"Unsupported equality
value type '{value.GetType()}'.")
};
x = Normalize(x);
y = Normalize(y);
return (x is null && y is null)
|| ReferenceEquals(x, y)
|| (x is P xp && y is P yp && Equals(xp, yp))
//|| (x is R xr && y is R yr && Equals(xr, yr))
;
}
It's unlikely probably would see an R clause (returned class), as
contrasted with the P clause (primitive class).
The Normalize local function is also geared at any rate along the same
lines to compare vis-a-vis the primitive type.
Then Equals(P, P), after having ruled out null and reference equality, base
implementation whether P is IEquatable<P> can just do it then.
Allowing for authors to extend as needed.
On Tuesday, June 10, 2025 at 1:13:17 PM UTC-4 Michael W Powell wrote:
> Hello,
>
> Double checking my work implementing IUserType. Implementing to facilitate
> mapping types to postgres Npgsql. Specifically in one case to JSON/JSONB
> column types, facilitated by either string, then to Newtonsoft.Json.Linq
> JObject or JArray, both JContainer, depending on the use case.
>
> Best I can figure, Assemble and Disassemble are somewhat core and central
> of such an implementation. Around the NullSafeGet and Set, for instance.
> Almost to a point where it might be worth providing a generic serialization
> implementation, interface, etc, but starting from here:
>
> public virtual object NullSafeGet(DbDataReader rs, string[] names,
> ISessionImplementor session, object owner)
> {
> this.VerifyNullSafeNames(names: names);
>
> var name = names[0];
> var ordinal = rs.GetOrdinal(name);
> var value = rs[ordinal];
> return value switch
> {
> null => null,
> P p => Assemble(p, owner),
> _ => throw new InvalidOperationException($"Unable to get null safe
> value, names: [{string.Join(", ", names)}].")
> };
> }
>
> public void NullSafeSet(DbCommand cmd, object value, int index,
> ISessionImplementor session)
> {
> // We expect there to be an parameter of this type.
> if (cmd.Parameters.TryGetValue<NpgsqlParameter>(index, out var arg))
> {
> // Parameter Value may be either null, of types R or P, otherwise
> throw.
> arg.Value = value switch
> {
> null => null,
> R r => Disassemble(r),
> P p => p,
> _ => throw new InvalidOperationException($"Unable to set null
> safe value type '{value.GetType()}' index {index}.")
> };
>
> // Indeed return here since we do not want to throw the default
> parameter ex.
> return;
> }
>
> throw new InvalidOperationException($"Unable to set null safe
> parameter value index {index}.");
> }
>
> Here I verify names apart from the implementation. Also I look up the
> postgres Npgsql parameter in this instance.
>
> But the core of the approach, I think, are Assemble and Disassemble, from
> what I can gather. Everything revolves around that, including DeepCopy.
>
> Mostly everything else is pretty boilerplate, in my estimation, so any
> specialization can focus on the A/D overrides. Sometimes perhaps also the
> Equals.
>
> public abstract class NpgsqlJsonCustomTypeBase<P, R> : IUserType
> {
> // ...
> }
>
> Have verified through mappings and to a test project, seems to satisfy
> things.
>
> Posting here in case I am missing something, perhaps there are gaps I am
> unaware of.
>
> Appreciate the feedback.
>
> Best regards,
>
> Michael W. Powell
>
--
You received this message because you are subscribed to the Google Groups
"Fluent NHibernate" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion visit
https://groups.google.com/d/msgid/fluent-nhibernate/7f404b09-59ee-4565-9164-8cad298b308fn%40googlegroups.com.