Got at least one data fetching method working; turns out, we can't use a patched LogicStack to get the data

This commit is contained in:
2026-01-14 22:11:11 +01:00
parent 40a8431464
commit 3f7122d30a
350 changed files with 41444 additions and 119 deletions

View File

@@ -0,0 +1,100 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace Swan
{
/// <summary>
/// <para>Provides a way for types that override <see cref="object.GetHashCode"/>
/// to correctly generate a hash code from the actual status of an instance.</para>
/// <para><c>CompositeHashCode</c> must be used ONLY as a helper when implementing
/// <see cref="IEquatable{T}">IEquatable&lt;T&gt;</see> in a STANDARD way, i.e. when:</para>
/// <list type="bullet">
/// <item><description>two instances having the same hash code are actually
/// interchangeable, i.e. they represent exactly the same object (for instance,
/// they should not coexist in a
/// <see cref="SortedSet{T}">SortedSet</see>);</description></item>
/// <item><description><see cref="object.GetHashCode">GetHashCode</see> and
/// <see cref="object.Equals(object)">Equals</see> are BOTH overridden, and the <c>Equals</c>
/// override either calls to the <see cref="IEquatable{T}.Equals(T)">IEquatable&lt;T&gt;.Equals</see>
/// (recommended) or performs exactly the same equality checks;</description></item>
/// <item><description>only "standard" equality checks are performed, i.e. by means of the
/// <c>==</c> operator, <see cref="IEquatable{T}">IEquatable&lt;T&gt;</see> interfaces, and
/// the <see cref="object.Equals(object)">Equals</see> method (for instance, this excludes case-insensitive
/// and/or culture-dependent string comparisons);
/// </description></item>
/// <item><description>the hash code is constructed (via <c>Using</c> calls) from the very same
/// fields and / or properties that are checked for equality.</description></item>
/// </list>
/// <para>For hashing to work correctly, all fields and/or properties involved in hashing must either
/// be immutable, or at least not change while an object is referenced in a hashtable.
/// This does not refer just to <c>System.Collections.Hashtable</c>; the .NET
/// Framework makes a fairly extensive use of hashing, for example in
/// <see cref="SortedSet{T}">SortedSet&lt;T&gt;</see>
/// and in various parts of LINQ. As a thumb rule, an object must stay the same during the execution of a
/// LINQ query on an <see cref="IEnumerable{T}">IEnumerable</see>
/// in which it is contained, as well as all the time it is referenced in a <c>Hashtable</c> or <c>SortedSet</c>.</para>
/// </summary>
/// <example>
/// <para>The following code constitutes a minimal use case for <c>CompositeHashCode</c>, as well
/// as a reference for standard <see cref="System.IEquatable{T}">IEquatable&lt;T&gt;</see> implementation.</para>
/// <para>Notice that all relevant properties are immutable; this is not, as stated in the summary,
/// an absolute requirement, but it surely helps and should be done every time it makes sense.</para>
/// <code>using System;
/// using Swan;
///
/// namespace Example
/// {
/// public class Person : IEquatable&lt;Person&gt;
/// {
/// public string Name { get; private set; }
///
/// public int Age { get; private set; }
///
/// public Person(string name, int age)
/// {
/// Name = name;
/// Age = age;
/// }
///
/// public override int GetHashCode() => CompositeHashCode.Using(Name, Age);
///
/// public override bool Equals(object obj) => obj is Person other &amp;&amp; Equals(other);
///
/// public bool Equals(Person other)
/// => other != null
/// &amp;&amp; other.Name == Name
/// &amp;&amp; other.Age == Age;
/// }
/// }</code>
/// </example>
public static class CompositeHashCode
{
#region Private constants
private const int InitialSeed = 17;
private const int Multiplier = 29;
#endregion
#region Public API
/// <summary>
/// Computes a hash code, taking into consideration the values of the specified
/// fields and/oror properties as part of an object's state. See the
/// <see cref="CompositeHashCode">example</see>.
/// </summary>
/// <param name="fields">The values of the fields and/or properties.</param>
/// <returns>The computed has code.</returns>
public static int Using(params object[] fields)
{
unchecked
{
return fields.Where(f => !(f is null))
.Aggregate(InitialSeed, (current, field) => (Multiplier * current) + field.GetHashCode());
}
}
#endregion
}
}