language-ext v3.3.41 Release Notes

Release Date: 2019-11-28 // over 4 years ago
  • 🚀 This is the first-pass release of the LanguageExt.CodeGen feature for generating record types. This means there's no need to derive from Record<TYPE> any more, and also allows records to be structs, which is a real bonus.

    To create a new record, simply attach the [Record] attribute to a partial class or a partial struct:

     [Record] public partial struct Person { public readonly string Forename; public readonly string Surname; }
    

    You may also use properties:

     [Record] public partial struct Person { public string Forename { get; } public string Surname { get; } }
    

    As well as computed properties:

     [Record] public partial struct Person { public string Forename { get; } public string Surname { get; } public string FullName =\> $"{Forename} {Surname}"; }
    

    The features of the generated record are:

    • Auto constructor provision
    • Auto deconstructor provision
    • Structural equality (with equality operators also)
    • Structural ordering (with ordering operators also)
    • GetHashCode provision
    • Serialisation
    • 0️⃣ Sensible default ToString implementation
    • With method for immutable transformation
    • Lens fields for composing nested immutable type transformation

    0️⃣ Coming soon (for both records and unions) is the ability to provide class-instances to override the default behaviour of equality, ordering, hash-code generation, and constructor validation.

    The generated code looks like this:

     [System.Serializable] public partial struct Person : System.IEquatable\<Person\>, System.IComparable\<Person\>, System.IComparable, System.Runtime.Serialization.ISerializable { public Person(string Forename, string Surname) { this.Forename = Forename; this.Surname = Surname; } public void Deconstruct(out string Forename, out string Surname) { Forename = this.Forename; Surname = this.Surname; } public Person(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { this.Forename = (string)info.GetValue("Forename", typeof(string)); this.Surname = (string)info.GetValue("Surname", typeof(string)); } public void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { info.AddValue("Forename", this.Forename); info.AddValue("Surname", this.Surname); } public static bool operator ==(Person x, Person y) =\> x.Equals(y); public static bool operator !=(Person x, Person y) =\> !(x == y); public static bool operator\>(Person x, Person y) =\> x.CompareTo(y) \> 0; public static bool operator \<(Person x, Person y) =\> x.CompareTo(y) \< 0; public static bool operator \>=(Person x, Person y) =\> x.CompareTo(y) \>= 0; public static bool operator \<=(Person x, Person y) =\> x.CompareTo(y) \<= 0; public bool Equals(Person other) { if (LanguageExt.Prelude.isnull(other)) return false; if (!default(LanguageExt.ClassInstances.EqDefault\<string\>).Equals(this.Forename, other.Forename)) return false; if (!default(LanguageExt.ClassInstances.EqDefault\<string\>).Equals(this.Surname, other.Surname)) return false; return true; } public override bool Equals(object obj) =\> obj is Person tobj && Equals(tobj); public int CompareTo(object obj) =\> obj is Person p ? CompareTo(p) : 1; public int CompareTo(Person other) { if (LanguageExt.Prelude.isnull(other)) return 1; int cmp = 0; cmp = default(LanguageExt.ClassInstances.OrdDefault\<string\>).Compare(this.Forename, other.Forename); if (cmp != 0) return cmp; cmp = default(LanguageExt.ClassInstances.OrdDefault\<string\>).Compare(this.Surname, other.Surname); if (cmp != 0) return cmp; return 0; } public override int GetHashCode() { const int fnvOffsetBasis = -2128831035; const int fnvPrime = 16777619; int state = fnvOffsetBasis; unchecked { state = (default(LanguageExt.ClassInstances.EqDefault\<string\>).GetHashCode(this.Forename) ^ state) \* fnvPrime; state = (default(LanguageExt.ClassInstances.EqDefault\<string\>).GetHashCode(this.Surname) ^ state) \* fnvPrime; } return state; } public override string ToString() { var sb = new System.Text.StringBuilder(); sb.Append("Person("); sb.Append(LanguageExt.Prelude.isnull(Forename) ? $"Forename: [null]" : $"Forename: {Forename}"); sb.Append($", "); sb.Append(LanguageExt.Prelude.isnull(Surname) ? $"Surname: [null]" : $"Surname: {Surname}"); sb.Append(")"); return sb.ToString(); } public Person With(string Forename = null, string Surname = null) =\> new Person(Forename ?? this.Forename, Surname ?? this.Surname); public static readonly Lens\<Person, string\> forename = Lens\<Person, string\>.New(\_x =\> \_x.Forename, \_x =\> \_y =\> \_y.With(Forename: \_x)); public static readonly Lens\<Person, string\> surname = Lens\<Person, string\>.New(\_x =\> \_x.Surname, \_x =\> \_y =\> \_y.With(Surname: \_x)); }