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 fromRecord<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 apartial class
or apartial 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 transformationLens
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)); }