From 53737a8e1c4d1d6def681068a2cb86bef3692f04 Mon Sep 17 00:00:00 2001 From: ig Date: Sun, 26 Feb 2023 15:39:55 +0100 Subject: [PATCH] Completely rewrite Units.csproj --- csharp/Lib/Units/Angle.cs | 56 ++---------------- csharp/Lib/Units/ApparentPower.cs | 16 +++++ csharp/Lib/Units/Composite/Ac1Phase.cs | 14 ++--- csharp/Lib/Units/Composite/Ac3Phase.cs | 10 +++- csharp/Lib/Units/Composite/AcPhase.cs | 10 ++-- csharp/Lib/Units/Frequency.cs | 54 ++--------------- .../Lib/Units/Generator/GenerateAttribute.cs | 5 ++ csharp/Lib/Units/Generator/Template.txt | 46 +++++++++++++++ csharp/Lib/Units/Generator/generate.sh | 13 +++++ csharp/Lib/Units/Power.cs | 55 ++---------------- csharp/Lib/Units/Power.generated.cs | 46 +++++++++++++++ csharp/Lib/Units/ReactivePower.cs | 13 +++++ csharp/Lib/Units/Resistance.cs | 54 ++--------------- csharp/Lib/Units/Temperature.cs | 57 ++---------------- csharp/Lib/Units/Units.cs | 17 ++++-- csharp/Lib/Units/Units.csproj | 9 ++- csharp/Lib/Units/Voltage.cs | 58 ++----------------- 17 files changed, 199 insertions(+), 334 deletions(-) create mode 100644 csharp/Lib/Units/ApparentPower.cs create mode 100644 csharp/Lib/Units/Generator/GenerateAttribute.cs create mode 100644 csharp/Lib/Units/Generator/Template.txt create mode 100755 csharp/Lib/Units/Generator/generate.sh create mode 100644 csharp/Lib/Units/Power.generated.cs create mode 100644 csharp/Lib/Units/ReactivePower.cs diff --git a/csharp/Lib/Units/Angle.cs b/csharp/Lib/Units/Angle.cs index 0f0aa7d8f..87a3ed2b4 100644 --- a/csharp/Lib/Units/Angle.cs +++ b/csharp/Lib/Units/Angle.cs @@ -1,20 +1,17 @@ using DecimalMath; +using InnovEnergy.Lib.Units.Generator; using InnovEnergy.Lib.Utils; namespace InnovEnergy.Lib.Units; -using T = Angle; - -public readonly struct Angle +[Generate] +public readonly partial struct Angle { - - public static String Unit => "rad"; public static String Symbol => "∠"; public static readonly Angle Pi = new Angle(DecimalEx.Pi); - public Decimal Value { get; } public Angle(Decimal value) { @@ -24,50 +21,5 @@ public readonly struct Angle ? modulo - DecimalEx.TwoPi : modulo; } - - public override String ToString() => Value + Unit; - - - #region scalar multiplication - - public static Angle operator *(Decimal scalar, Angle angle ) => new Angle(scalar * angle.Value); - public static Angle operator *(Angle angle , Decimal scalar) => new Angle(scalar * angle.Value); - public static Angle operator /(Angle angle , Decimal scalar) => new Angle(angle.Value / scalar); - - #endregion - - #region addition - - public static T operator +(T left, T right) => new T(left.Value + right.Value); - public static T operator -(T left, T right) => new T(left.Value - right.Value); - public static T operator -(T t) => new T(-t.Value); - - #endregion - - #region compare - - public static Boolean operator ==(T left, T right) => left.Value == right.Value; - public static Boolean operator !=(T left, T right) => left.Value != right.Value; - public static Boolean operator > (T left, T right) => left.Value > right.Value; - public static Boolean operator < (T left, T right) => left.Value < right.Value; - public static Boolean operator >=(T left, T right) => left.Value >= right.Value; - public static Boolean operator <=(T left, T right) => left.Value <= right.Value; - - #endregion - - #region conversion - - public static implicit operator T(Decimal d) => new T(d); - public static implicit operator T(Double d) => new T((Decimal)d); - public static implicit operator T(Int32 i) => new T(i); - public static implicit operator Decimal(T t) => t.Value; - - #endregion - - #region equality - - public override Boolean Equals(Object? obj) => obj is T other && Equals(other); - public override Int32 GetHashCode() => Value.GetHashCode(); - - #endregion + } \ No newline at end of file diff --git a/csharp/Lib/Units/ApparentPower.cs b/csharp/Lib/Units/ApparentPower.cs new file mode 100644 index 000000000..b2a5bba6c --- /dev/null +++ b/csharp/Lib/Units/ApparentPower.cs @@ -0,0 +1,16 @@ +using InnovEnergy.Lib.Units.Generator; + +namespace InnovEnergy.Lib.Units; + +[Generate] +public readonly partial struct ApparentPower +{ + public static String Unit => "VA"; + public static String Symbol => "S"; + + public ApparentPower(Decimal value) + { + if (value < 0) throw new ArgumentException("Apparent power cannot be negative", nameof(value)); + Value = value; + } +} \ No newline at end of file diff --git a/csharp/Lib/Units/Composite/Ac1Phase.cs b/csharp/Lib/Units/Composite/Ac1Phase.cs index e9970378b..00f823791 100644 --- a/csharp/Lib/Units/Composite/Ac1Phase.cs +++ b/csharp/Lib/Units/Composite/Ac1Phase.cs @@ -1,10 +1,10 @@ namespace InnovEnergy.Lib.Units.Composite; public record Ac1Phase - ( - Voltage Voltage, - Current Current, - Angle Phi, - Frequency Frequency - ) : - AcPhase(Voltage, Current, Phi); \ No newline at end of file +( + Voltage Voltage, + Current Current, + Angle Phi, + Frequency Frequency +) : +AcPhase(Voltage, Current, Phi); \ No newline at end of file diff --git a/csharp/Lib/Units/Composite/Ac3Phase.cs b/csharp/Lib/Units/Composite/Ac3Phase.cs index 1fc44306f..be4f7c73d 100644 --- a/csharp/Lib/Units/Composite/Ac3Phase.cs +++ b/csharp/Lib/Units/Composite/Ac3Phase.cs @@ -1,8 +1,12 @@ +using static DecimalMath.DecimalEx; + namespace InnovEnergy.Lib.Units.Composite; public record Ac3Phase(AcPhase L1, AcPhase L2, AcPhase L3, Decimal Frequency) { - public Power ApparentPower => L1.ApparentPower + L2.ApparentPower + L3.ApparentPower; - public Power ReactivePower => L1.ReactivePower + L2.ReactivePower + L3.ReactivePower; - public Power ActivePower => L1.ActivePower + L2.ActivePower + L3.ActivePower; + public ApparentPower ApparentPower => L1.ApparentPower + L2.ApparentPower + L3.ApparentPower; + public ReactivePower ReactivePower => L1.ReactivePower + L2.ReactivePower + L3.ReactivePower; + public Power ActivePower => L1.ActivePower + L2.ActivePower + L3.ActivePower; + + public Angle Phi => ATan2(ReactivePower, ActivePower); } \ No newline at end of file diff --git a/csharp/Lib/Units/Composite/AcPhase.cs b/csharp/Lib/Units/Composite/AcPhase.cs index c616b9c57..f194f28af 100644 --- a/csharp/Lib/Units/Composite/AcPhase.cs +++ b/csharp/Lib/Units/Composite/AcPhase.cs @@ -5,7 +5,7 @@ namespace InnovEnergy.Lib.Units.Composite; public record AcPhase : Phase { - protected AcPhase(Voltage voltage, Current current, Angle phi) : base(voltage, current) + public AcPhase(Voltage voltage, Current current, Angle phi) : base(voltage, current) { if (voltage < 0) throw new ArgumentException("RMS value cannot be negative", nameof(voltage)); if (current < 0) throw new ArgumentException("RMS value cannot be negative", nameof(current)); @@ -15,8 +15,8 @@ public record AcPhase : Phase public Angle Phi { get; } - public Power ApparentPower => Voltage * Current; - public Power ActivePower => ApparentPower * PowerFactor; - public Power ReactivePower => ApparentPower * Sin(Phi); - public Decimal PowerFactor => Cos(Phi); + public ApparentPower ApparentPower => Math.Abs(Voltage.Value * Current.Value) ; + public Power ActivePower => ApparentPower.Value * PowerFactor; + public ReactivePower ReactivePower => ApparentPower.Value * Sin(Phi); + public Decimal PowerFactor => Cos(Phi); } \ No newline at end of file diff --git a/csharp/Lib/Units/Frequency.cs b/csharp/Lib/Units/Frequency.cs index 91a3e3849..173f5037d 100644 --- a/csharp/Lib/Units/Frequency.cs +++ b/csharp/Lib/Units/Frequency.cs @@ -1,59 +1,13 @@ +using InnovEnergy.Lib.Units.Generator; + namespace InnovEnergy.Lib.Units; -using T = Frequency; -public readonly struct Frequency +[Generate] +public readonly partial struct Frequency { public static String Unit => "Hz"; public static String Symbol => "f"; - public Decimal Value { get; } - public Frequency(Decimal value) => Value = value; - - public override String ToString() => Value + Unit; - - #region scalar multiplication - - public static T operator *(Decimal scalar, T t) => new T(scalar * t.Value); - public static T operator *(T t, Decimal scalar) => new T(scalar * t.Value); - public static T operator /(T t, Decimal scalar) => new T(t.Value / scalar); - - #endregion - - #region addition - - public static T operator +(T left, T right) => new T(left.Value + right.Value); - public static T operator -(T left, T right) => new T(left.Value - right.Value); - public static T operator -(T t) => new T(-t.Value); - - #endregion - - #region compare - - public static Boolean operator ==(T left, T right) => left.Value == right.Value; - public static Boolean operator !=(T left, T right) => left.Value != right.Value; - public static Boolean operator > (T left, T right) => left.Value > right.Value; - public static Boolean operator < (T left, T right) => left.Value < right.Value; - public static Boolean operator >=(T left, T right) => left.Value >= right.Value; - public static Boolean operator <=(T left, T right) => left.Value <= right.Value; - - #endregion - - #region conversion - - public static implicit operator T(Decimal d) => new T(d); - public static implicit operator T(Double d) => new T((Decimal)d); - public static implicit operator T(Int32 i) => new T(i); - public static implicit operator Decimal(T t) => t.Value; - - #endregion - - #region equality - - public Boolean Equals(T other) => Value == other.Value; - public override Boolean Equals(Object? obj) => obj is T other && Equals(other); - public override Int32 GetHashCode() => Value.GetHashCode(); - - #endregion } \ No newline at end of file diff --git a/csharp/Lib/Units/Generator/GenerateAttribute.cs b/csharp/Lib/Units/Generator/GenerateAttribute.cs new file mode 100644 index 000000000..c6643d2d7 --- /dev/null +++ b/csharp/Lib/Units/Generator/GenerateAttribute.cs @@ -0,0 +1,5 @@ +namespace InnovEnergy.Lib.Units.Generator; + +[AttributeUsage(AttributeTargets.Struct)] +internal class GenerateAttribute: Attribute +{} \ No newline at end of file diff --git a/csharp/Lib/Units/Generator/Template.txt b/csharp/Lib/Units/Generator/Template.txt new file mode 100644 index 000000000..6055ace01 --- /dev/null +++ b/csharp/Lib/Units/Generator/Template.txt @@ -0,0 +1,46 @@ +#nullable enable // Auto-generated code requires an explicit '#nullable' directive in source. + +namespace InnovEnergy.Lib.Units; + +using T = Template; + +public readonly partial struct Template +{ + public Decimal Value { get; } + public override String ToString() => Value + Unit; + + // scalar multiplication + + public static T operator *(Decimal scalar, T t) => new T(scalar * t.Value); + public static T operator *(T t, Decimal scalar) => new T(scalar * t.Value); + public static T operator /(T t, Decimal scalar) => new T(t.Value / scalar); + + // addition + + public static T operator +(T left, T right) => new T(left.Value + right.Value); + public static T operator -(T left, T right) => new T(left.Value - right.Value); + public static T operator -(T t) => new T(-t.Value); + + // compare + + public static Boolean operator ==(T left, T right) => left.Value == right.Value; + public static Boolean operator !=(T left, T right) => left.Value != right.Value; + public static Boolean operator > (T left, T right) => left.Value > right.Value; + public static Boolean operator < (T left, T right) => left.Value < right.Value; + public static Boolean operator >=(T left, T right) => left.Value >= right.Value; + public static Boolean operator <=(T left, T right) => left.Value <= right.Value; + + // conversion + + public static implicit operator T(Decimal d) => new T(d); + public static implicit operator T(Double d) => new T((Decimal)d); + public static implicit operator T(Int32 i) => new T(i); + public static implicit operator Decimal(T t) => t.Value; + + // equality + + public Boolean Equals(T other) => Value == other.Value; + public override Boolean Equals(Object? obj) => obj is T other && Equals(other); + public override Int32 GetHashCode() => Value.GetHashCode(); + +} diff --git a/csharp/Lib/Units/Generator/generate.sh b/csharp/Lib/Units/Generator/generate.sh new file mode 100755 index 000000000..01ff06f64 --- /dev/null +++ b/csharp/Lib/Units/Generator/generate.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash + + +scriptDir=$( dirname -- "$0"; ) +cd "$scriptDir/.." || exit + +for file in $(grep -l '\[Generate\]' *.cs) +do + filename=$(basename -- "$file") + class="${filename%.*}" + echo "generating $filename" + sed "s/Template/$class/g" "./Generator/Template.txt" > "./$class.generated.cs" +done \ No newline at end of file diff --git a/csharp/Lib/Units/Power.cs b/csharp/Lib/Units/Power.cs index 4bc44a53a..716336a5e 100644 --- a/csharp/Lib/Units/Power.cs +++ b/csharp/Lib/Units/Power.cs @@ -1,66 +1,19 @@ +using InnovEnergy.Lib.Units.Generator; + namespace InnovEnergy.Lib.Units; -using T = Power; - -public readonly struct Power +[Generate] +public readonly partial struct Power { public static String Unit => "W"; public static String Symbol => "P"; - - public Decimal Value { get; } public Power(Decimal value) => Value = value; - public override String ToString() => Value + Unit; - // P=UI public static Voltage operator /(Power power, Current current) => new Voltage(power.Value / current.Value); public static Current operator /(Power power, Voltage voltage) => new Current(power.Value / voltage.Value); - #region scalar multiplication - - public static T operator *(Decimal scalar, T t) => new T(scalar * t.Value); - public static T operator *(T t, Decimal scalar) => new T(scalar * t.Value); - public static T operator /(T t, Decimal scalar) => new T(t.Value / scalar); - - #endregion - - #region addition - - public static T operator +(T left, T right) => new T(left.Value + right.Value); - public static T operator -(T left, T right) => new T(left.Value - right.Value); - public static T operator -(T t) => new T(-t.Value); - - #endregion - - #region compare - - public static Boolean operator ==(T left, T right) => left.Value == right.Value; - public static Boolean operator !=(T left, T right) => left.Value != right.Value; - public static Boolean operator > (T left, T right) => left.Value > right.Value; - public static Boolean operator < (T left, T right) => left.Value < right.Value; - public static Boolean operator >=(T left, T right) => left.Value >= right.Value; - public static Boolean operator <=(T left, T right) => left.Value <= right.Value; - - #endregion - - #region conversion - - public static implicit operator T(Decimal d) => new T(d); - public static implicit operator T(Double d) => new T((Decimal)d); - public static implicit operator T(Int32 i) => new T(i); - public static implicit operator Decimal(T t) => t.Value; - - #endregion - - #region equality - - public Boolean Equals(T other) => Value == other.Value; - public override Boolean Equals(Object? obj) => obj is T other && Equals(other); - public override Int32 GetHashCode() => Value.GetHashCode(); - - #endregion - } \ No newline at end of file diff --git a/csharp/Lib/Units/Power.generated.cs b/csharp/Lib/Units/Power.generated.cs new file mode 100644 index 000000000..3d4d12a65 --- /dev/null +++ b/csharp/Lib/Units/Power.generated.cs @@ -0,0 +1,46 @@ +#nullable enable // Auto-generated code requires an explicit '#nullable' directive in source. + +namespace InnovEnergy.Lib.Units; + +using T = ReactivePower; + +public readonly partial struct ReactivePower +{ + public Decimal Value { get; } + public override String ToString() => Value + Unit; + + // scalar multiplication + + public static T operator *(Decimal scalar, T t) => new T(scalar * t.Value); + public static T operator *(T t, Decimal scalar) => new T(scalar * t.Value); + public static T operator /(T t, Decimal scalar) => new T(t.Value / scalar); + + // addition + + public static T operator +(T left, T right) => new T(left.Value + right.Value); + public static T operator -(T left, T right) => new T(left.Value - right.Value); + public static T operator -(T t) => new T(-t.Value); + + // compare + + public static Boolean operator ==(T left, T right) => left.Value == right.Value; + public static Boolean operator !=(T left, T right) => left.Value != right.Value; + public static Boolean operator > (T left, T right) => left.Value > right.Value; + public static Boolean operator < (T left, T right) => left.Value < right.Value; + public static Boolean operator >=(T left, T right) => left.Value >= right.Value; + public static Boolean operator <=(T left, T right) => left.Value <= right.Value; + + // conversion + + public static implicit operator T(Decimal d) => new T(d); + public static implicit operator T(Double d) => new T((Decimal)d); + public static implicit operator T(Int32 i) => new T(i); + public static implicit operator Decimal(T t) => t.Value; + + // equality + + public Boolean Equals(T other) => Value == other.Value; + public override Boolean Equals(Object? obj) => obj is T other && Equals(other); + public override Int32 GetHashCode() => Value.GetHashCode(); + +} \ No newline at end of file diff --git a/csharp/Lib/Units/ReactivePower.cs b/csharp/Lib/Units/ReactivePower.cs new file mode 100644 index 000000000..a7017cb32 --- /dev/null +++ b/csharp/Lib/Units/ReactivePower.cs @@ -0,0 +1,13 @@ + +using InnovEnergy.Lib.Units.Generator; + +namespace InnovEnergy.Lib.Units; + +[Generate] +public readonly partial struct ReactivePower +{ + public static String Unit => "var"; + public static String Symbol => "Q"; + + public ReactivePower(Decimal value) => Value = value; +} \ No newline at end of file diff --git a/csharp/Lib/Units/Resistance.cs b/csharp/Lib/Units/Resistance.cs index c3c0b34c0..f31cd4a4b 100644 --- a/csharp/Lib/Units/Resistance.cs +++ b/csharp/Lib/Units/Resistance.cs @@ -1,63 +1,19 @@ +using InnovEnergy.Lib.Units.Generator; + namespace InnovEnergy.Lib.Units; -using T = Resistance; - -public readonly struct Resistance +[Generate] +public readonly partial struct Resistance { public static String Unit => "Ω"; public static String Symbol => "R"; - public Decimal Value { get; } public Resistance(Decimal value) => Value = value; - public override String ToString() => Value + Unit; - // U=RI public static Voltage operator *(Resistance resistance, Current current) => new Voltage(resistance.Value * current.Value); - #region scalar multiplication - - public static T operator *(Decimal scalar, T t) => new T(scalar * t.Value); - public static T operator *(T t, Decimal scalar) => new T(scalar * t.Value); - public static T operator /(T t, Decimal scalar) => new T(t.Value / scalar); - - #endregion - - #region addition - - public static T operator +(T left, T right) => new T(left.Value + right.Value); - public static T operator -(T left, T right) => new T(left.Value - right.Value); - public static T operator -(T t) => new T(-t.Value); - - #endregion - - #region compare - - public static Boolean operator ==(T left, T right) => left.Value == right.Value; - public static Boolean operator !=(T left, T right) => left.Value != right.Value; - public static Boolean operator > (T left, T right) => left.Value > right.Value; - public static Boolean operator < (T left, T right) => left.Value < right.Value; - public static Boolean operator >=(T left, T right) => left.Value >= right.Value; - public static Boolean operator <=(T left, T right) => left.Value <= right.Value; - - #endregion - - #region conversion - - public static implicit operator T(Decimal d) => new T(d); - public static implicit operator T(Double d) => new T((Decimal)d); - public static implicit operator T(Int32 i) => new T(i); - public static implicit operator Decimal(T t) => t.Value; - - #endregion - - #region equality - - public Boolean Equals(T other) => Value == other.Value; - public override Boolean Equals(Object? obj) => obj is T other && Equals(other); - public override Int32 GetHashCode() => Value.GetHashCode(); - - #endregion + } \ No newline at end of file diff --git a/csharp/Lib/Units/Temperature.cs b/csharp/Lib/Units/Temperature.cs index 22a411338..243487d7f 100644 --- a/csharp/Lib/Units/Temperature.cs +++ b/csharp/Lib/Units/Temperature.cs @@ -1,61 +1,12 @@ +using InnovEnergy.Lib.Units.Generator; + namespace InnovEnergy.Lib.Units; -using T = Temperature; - -public readonly struct Temperature +[Generate] +public readonly partial struct Temperature { public static String Unit => "°C"; public static String Symbol => "T"; - public Decimal Value { get; } - public Temperature(Decimal value) => Value = value; - - public override String ToString() => Value + Unit; - - - #region scalar multiplication - - public static T operator *(Decimal scalar, T t) => new T(scalar * t.Value); - public static T operator *(T t, Decimal scalar) => new T(scalar * t.Value); - public static T operator /(T t, Decimal scalar) => new T(t.Value / scalar); - - #endregion - - #region addition - - public static T operator +(T left, T right) => new T(left.Value + right.Value); - public static T operator -(T left, T right) => new T(left.Value - right.Value); - public static T operator -(T t) => new T(-t.Value); - - #endregion - - #region compare - - public static Boolean operator ==(T left, T right) => left.Value == right.Value; - public static Boolean operator !=(T left, T right) => left.Value != right.Value; - public static Boolean operator > (T left, T right) => left.Value > right.Value; - public static Boolean operator < (T left, T right) => left.Value < right.Value; - public static Boolean operator >=(T left, T right) => left.Value >= right.Value; - public static Boolean operator <=(T left, T right) => left.Value <= right.Value; - - #endregion - - #region conversion - - public static implicit operator T(Decimal d) => new T(d); - public static implicit operator T(Double d) => new T((Decimal)d); - public static implicit operator T(Int32 i) => new T(i); - public static implicit operator Decimal(T t) => t.Value; - - #endregion - - #region equality - - public Boolean Equals(T other) => Value == other.Value; - public override Boolean Equals(Object? obj) => obj is T other && Equals(other); - public override Int32 GetHashCode() => Value.GetHashCode(); - - #endregion - } \ No newline at end of file diff --git a/csharp/Lib/Units/Units.cs b/csharp/Lib/Units/Units.cs index 88b9e04aa..de1b246ad 100644 --- a/csharp/Lib/Units/Units.cs +++ b/csharp/Lib/Units/Units.cs @@ -5,16 +5,23 @@ namespace InnovEnergy.Lib.Units; public static class Units { - public static Current A (this Decimal value) => new Current(value); - public static Voltage V (this Decimal value) => new Voltage(value); - public static Power W (this Decimal value) => new Power(value); - public static Resistance Ohm(this Decimal value) => new Resistance(value); + public static Current A (this Decimal value) => new Current(value); + public static Voltage V (this Decimal value) => new Voltage(value); + public static Power W (this Decimal value) => new Power(value); + public static ReactivePower Var (this Decimal value) => new ReactivePower(value); + public static ApparentPower Va (this Decimal value) => new ApparentPower(value); + public static Resistance Ohm (this Decimal value) => new Resistance(value); + public static Frequency Hz (this Decimal value) => new Frequency(value); + public static Angle Rad (this Decimal value) => new Angle(value); + public static Temperature Celsius(this Decimal value) => new Temperature(value); public static readonly IReadOnlyList JsonConverters = new JsonConverter[] { new CurrentConverter(), new VoltageConverter(), new PowerConverter(), - new ResistanceConverter() + new ResistanceConverter(), + + // TODO }; } \ No newline at end of file diff --git a/csharp/Lib/Units/Units.csproj b/csharp/Lib/Units/Units.csproj index eab4f3f58..4cedc809f 100644 --- a/csharp/Lib/Units/Units.csproj +++ b/csharp/Lib/Units/Units.csproj @@ -1,11 +1,6 @@ - - Library - preview - - @@ -14,4 +9,8 @@ + + + + diff --git a/csharp/Lib/Units/Voltage.cs b/csharp/Lib/Units/Voltage.cs index db75e63e0..5bbfc088f 100644 --- a/csharp/Lib/Units/Voltage.cs +++ b/csharp/Lib/Units/Voltage.cs @@ -1,69 +1,19 @@ +using InnovEnergy.Lib.Units.Generator; + namespace InnovEnergy.Lib.Units; -using T = Voltage; - -public readonly struct Voltage +[Generate] +public readonly partial struct Voltage { public static String Unit => "V"; public static String Symbol => "U"; - - public Decimal Value { get; } public Voltage(Decimal value) => Value = value; - public override String ToString() => Value + Unit; // U=RI public static Current operator /(Voltage voltage, Resistance resistance) => new Current(voltage.Value / resistance.Value); // P=UI public static Power operator *(Voltage voltage, Current current) => new Power(current.Value * voltage.Value); - - - #region scalar multiplication - - public static T operator *(Decimal scalar, T t) => new T(scalar * t.Value); - public static T operator *(T t, Decimal scalar) => new T(scalar * t.Value); - public static T operator /(T t, Decimal scalar) => new T(t.Value / scalar); - - #endregion - - #region addition - - public static T operator +(T left, T right) => new T(left.Value + right.Value); - public static T operator -(T left, T right) => new T(left.Value - right.Value); - public static T operator -(T t) => new T(-t.Value); - - #endregion - - #region compare - - public static Boolean operator ==(T left, T right) => left.Value == right.Value; - public static Boolean operator !=(T left, T right) => left.Value != right.Value; - public static Boolean operator > (T left, T right) => left.Value > right.Value; - public static Boolean operator < (T left, T right) => left.Value < right.Value; - public static Boolean operator >=(T left, T right) => left.Value >= right.Value; - public static Boolean operator <=(T left, T right) => left.Value <= right.Value; - - #endregion - - #region conversion - - public static implicit operator T(Decimal d) => new T(d); - public static implicit operator T(Double d) => new T((Decimal)d); - public static implicit operator T(Int32 i) => new T(i); - public static implicit operator Decimal(T t) => t.Value; - - #endregion - - #region equality - - public Boolean Equals(T other) => Value == other.Value; - public override Boolean Equals(Object? obj) => obj is T other && Equals(other); - public override Int32 GetHashCode() => Value.GetHashCode(); - - #endregion - - - } \ No newline at end of file