using System; namespace SessionCompanion.Extensions.EitherType { public class Either { /// /// Kontruktor dla lewej zmiennej /// /// Wartość lewej zmiennej public Either(TL left) { this.Left = left; this.IsLeft = true; } /// /// Konstruktor dla prawej zmiennej /// /// Wartość prawej zmiennej public Either(TR right) { this.Right = right; this.IsLeft = false; } /// /// Lewa zmienna /// public TL Left { get; } /// /// Prawa zmienna /// public TR Right { get; } /// /// Zmienna informujaca czy wykorzystana zostąła zmienna lewa czy prawa /// public bool IsLeft { get; } /// /// Tworzy obiekt typu Either wykorzystując zmienną lewą /// /// Wartość lewej zmiennej public static implicit operator Either(TL left) => new Either(left); /// /// Tworzy obiekt typu Either wykorzystując zmienną prawą /// /// Wartosć prawej zmiennej public static implicit operator Either(TR right) => new Either(right); /// /// Bazowa metoda dopasowania wzorów. /// Jeśli podana jest wartość lewa, to Match zwróci wynik lewej funkcji, w przeciwnym razie wynik prawej funkcji. /// /// Typ zwracanej wartości /// Lewa funkcja /// Prawa funkcja /// Wynik prawej/lewej funkcji public T Match(Func leftFunc, Func rightFunc) { if (leftFunc == null) { throw new ArgumentNullException(nameof(leftFunc)); } if (rightFunc == null) { throw new ArgumentNullException(nameof(rightFunc)); } return this.IsLeft ? leftFunc(this.Left) : rightFunc(this.Right); } /// /// Bazowa metoda dopasowania wzorów. /// Jeśli podana jest wartość lewa, to Match wykona lewą funkcję, w przeciwnym razie wykona funkcję prawą. /// /// Lewa funkcja /// Prawa funkcja public void Match(Action leftFunc, Action rightFunc) { if (leftFunc == null) { throw new ArgumentNullException(nameof(leftFunc)); } if (rightFunc == null) { throw new ArgumentNullException(nameof(rightFunc)); } if (this.IsLeft) { leftFunc(this.Left); } else { rightFunc(this.Right); } } /// /// Funkcja ustala czy uzyta została lewa zmienna, jesli tak to zwraca jej wartość inaczej zwraca defaultowy obiekt /// o typie takim jak lewa zmienna /// /// Wartosć lewej zmiennej lub defaultową wartość o typie lewej zmiennej public TL LeftOrDefault() => this.Match(l => l, r => default(TL)); /// /// Funkcja ustala czy uzyta została prawa zmienna, jesli tak to zwraca jej wartość inaczej zwraca defaultowy obiekt /// o typie takim jak lewa zmienna /// /// Wartosć lewej zmiennej lub defaultową wartość o typie prawej zmiennej public TR RightOrDefault() => this.Match(l => default(TR), r => r); } }