From d701620d34af1fa5fbef2e3ceae7b7d9c2cfb8d6 Mon Sep 17 00:00:00 2001 From: ig Date: Tue, 13 Jun 2023 13:03:49 +0200 Subject: [PATCH] Units V2 --- csharp/Lib/Units/ActivePower.cs | 23 ------- csharp/Lib/Units/Angle.cs | 27 ++++---- csharp/Lib/Units/ApparentPower.cs | 17 ----- csharp/Lib/Units/Composite/Ac1Bus.cs | 19 +++--- csharp/Lib/Units/Composite/Ac3Bus.cs | 18 +++--- csharp/Lib/Units/Composite/AcPhase.cs | 15 +++-- csharp/Lib/Units/Composite/AcPower.cs | 25 +++++--- csharp/Lib/Units/Composite/Bus.cs | 11 ---- csharp/Lib/Units/Composite/DcBus.cs | 12 +++- csharp/Lib/Units/Current.cs | 21 +++---- csharp/Lib/Units/DcPower.cs | 22 ------- csharp/Lib/Units/Energy.cs | 18 +++--- csharp/Lib/Units/Frequency.cs | 16 ++--- csharp/Lib/Units/Percent.cs | 17 ++--- csharp/Lib/Units/Power/AcPower.cs | 8 +++ csharp/Lib/Units/Power/ActivePower.cs | 15 +++++ csharp/Lib/Units/Power/ApparentPower.cs | 14 +++++ csharp/Lib/Units/Power/DcPower.cs | 13 ++++ csharp/Lib/Units/Power/Power.cs | 9 +++ csharp/Lib/Units/Power/ReactivePower.cs | 14 +++++ csharp/Lib/Units/ReactivePower.cs | 12 ---- csharp/Lib/Units/Resistance.cs | 21 +++---- csharp/Lib/Units/Temperature.cs | 16 +++-- csharp/Lib/Units/Unit.cs | 11 ++++ csharp/Lib/Units/Units.cs | 83 +++++++++++++++++++------ csharp/Lib/Units/Voltage.cs | 19 +++--- 26 files changed, 268 insertions(+), 228 deletions(-) delete mode 100644 csharp/Lib/Units/ActivePower.cs delete mode 100644 csharp/Lib/Units/ApparentPower.cs delete mode 100644 csharp/Lib/Units/Composite/Bus.cs delete mode 100644 csharp/Lib/Units/DcPower.cs create mode 100644 csharp/Lib/Units/Power/AcPower.cs create mode 100644 csharp/Lib/Units/Power/ActivePower.cs create mode 100644 csharp/Lib/Units/Power/ApparentPower.cs create mode 100644 csharp/Lib/Units/Power/DcPower.cs create mode 100644 csharp/Lib/Units/Power/Power.cs create mode 100644 csharp/Lib/Units/Power/ReactivePower.cs delete mode 100644 csharp/Lib/Units/ReactivePower.cs create mode 100644 csharp/Lib/Units/Unit.cs diff --git a/csharp/Lib/Units/ActivePower.cs b/csharp/Lib/Units/ActivePower.cs deleted file mode 100644 index d1645cdf2..000000000 --- a/csharp/Lib/Units/ActivePower.cs +++ /dev/null @@ -1,23 +0,0 @@ -using InnovEnergy.Lib.SrcGen; -using InnovEnergy.Lib.SrcGen.Attributes; -using InnovEnergy.Lib.Time.Unix; - -namespace InnovEnergy.Lib.Units; - - -[Generate][Generate] -public readonly partial struct ActivePower -{ - public static String Unit => "W"; - public static String Symbol => "P"; - - // P=UI - public static Voltage operator /(ActivePower power, Current current) => new Voltage(power.Value / current.Value); - public static Current operator /(ActivePower power, Voltage voltage) => new Current(power.Value / voltage.Value); - - public static Energy operator *(ActivePower power, TimeSpan timeSpan) => power.Value / 1000 * timeSpan.TotalHours; - public static Energy operator *(TimeSpan timeSpan, ActivePower power) => power.Value / 1000 * timeSpan.TotalHours; - - public static Energy operator *(ActivePower power, UnixTimeSpan timeSpan) => power.Value * timeSpan.Ticks / 3_600_000; - public static Energy operator *(UnixTimeSpan timeSpan, ActivePower power) => power.Value * timeSpan.Ticks / 3_600_000; -} \ No newline at end of file diff --git a/csharp/Lib/Units/Angle.cs b/csharp/Lib/Units/Angle.cs index 28be3b6de..cdcd1bb50 100644 --- a/csharp/Lib/Units/Angle.cs +++ b/csharp/Lib/Units/Angle.cs @@ -1,21 +1,24 @@ -using InnovEnergy.Lib.SrcGen; -using InnovEnergy.Lib.SrcGen.Attributes; using static System.Math; namespace InnovEnergy.Lib.Units; -[Generate("HAS_CONSTRUCTOR")][Generate] -public readonly partial struct Angle +public sealed class Angle : Unit { - public static String Unit => "rad"; - public static String Symbol => "∠"; + public override String Symbol => "rad"; - public Angle(Double value) + public Angle(Double value): base(Normalize(value)) { - var modulo = value % Tau; // tau is 2pi - - Value = modulo > PI - ? modulo - Tau - : modulo; } + + private static Double Normalize(Double value) + { + var modulo = value % Tau; // tau is 2pi + + return modulo > PI + ? modulo - Tau + : modulo; + } + + public static implicit operator Angle(Double d) => new Angle(d); + public static implicit operator Double(Angle d) => d.Value; } \ No newline at end of file diff --git a/csharp/Lib/Units/ApparentPower.cs b/csharp/Lib/Units/ApparentPower.cs deleted file mode 100644 index 6acce8f7b..000000000 --- a/csharp/Lib/Units/ApparentPower.cs +++ /dev/null @@ -1,17 +0,0 @@ -using InnovEnergy.Lib.SrcGen; -using InnovEnergy.Lib.SrcGen.Attributes; - -namespace InnovEnergy.Lib.Units; - -[Generate("HAS_CONSTRUCTOR")][Generate] -public readonly partial struct ApparentPower -{ - public static String Unit => "VA"; - public static String Symbol => "S"; - - public ApparentPower(Double 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/Ac1Bus.cs b/csharp/Lib/Units/Composite/Ac1Bus.cs index 226f2104c..fd039647c 100644 --- a/csharp/Lib/Units/Composite/Ac1Bus.cs +++ b/csharp/Lib/Units/Composite/Ac1Bus.cs @@ -1,12 +1,14 @@ - namespace InnovEnergy.Lib.Units.Composite; -public record Ac1Bus : AcPhase +public sealed class Ac1Bus { - protected Ac1Bus() {} - - public Frequency Frequency { get; protected init; } + private Ac1Bus() + {} + public Voltage Voltage { get; private init; } = null!; + public Current Current { get; private init; } = null!; + public AcPower Power { get; private init; } = null!; + public Frequency Frequency { get; private init; } = null!; public static Ac1Bus FromVoltageCurrentFrequencyPhi(Double voltageRms, Double currentRms, @@ -17,8 +19,7 @@ public record Ac1Bus : AcPhase Current = currentRms, Voltage = voltageRms, Power = AcPower.FromVoltageCurrentPhi(voltageRms, currentRms, phi) - }; -} - - + }; + public static Ac1Bus Null { get; } = FromVoltageCurrentFrequencyPhi(0, 0, 0, 0); +} \ No newline at end of file diff --git a/csharp/Lib/Units/Composite/Ac3Bus.cs b/csharp/Lib/Units/Composite/Ac3Bus.cs index 8eaba22ad..61b9aed8a 100644 --- a/csharp/Lib/Units/Composite/Ac3Bus.cs +++ b/csharp/Lib/Units/Composite/Ac3Bus.cs @@ -2,17 +2,15 @@ namespace InnovEnergy.Lib.Units.Composite; -#pragma warning disable CS8618 - -public record Ac3Bus +public sealed class Ac3Bus { - protected Ac3Bus() {} + private Ac3Bus() {} - public AcPhase L1 { get; protected init; } - public AcPhase L2 { get; protected init; } - public AcPhase L3 { get; protected init; } - public AcPower Power { get; protected init; } - public Frequency Frequency { get; protected init; } + public AcPhase L1 { get; private init; } = null!; + public AcPhase L2 { get; private init; } = null!; + public AcPhase L3 { get; private init; } = null!; + public AcPower Power { get; private init; } = null!; + public Frequency Frequency { get; private init; } = null!; public static Ac3Bus FromPhasesAndFrequency(AcPhase l1, AcPhase l2, @@ -25,4 +23,6 @@ public record Ac3Bus Power = AcPower.SumOf(l1.Power, l2.Power, l3.Power), Frequency = frequency, }; + + public static Ac3Bus Null { get; } = FromPhasesAndFrequency(AcPhase.Null, AcPhase.Null, AcPhase.Null, 0); } \ No newline at end of file diff --git a/csharp/Lib/Units/Composite/AcPhase.cs b/csharp/Lib/Units/Composite/AcPhase.cs index 2ca82572d..a950ed246 100644 --- a/csharp/Lib/Units/Composite/AcPhase.cs +++ b/csharp/Lib/Units/Composite/AcPhase.cs @@ -1,12 +1,15 @@ +using InnovEnergy.Lib.Units.Power; + namespace InnovEnergy.Lib.Units.Composite; -#pragma warning disable CS8618 -public record AcPhase : Bus +public sealed class AcPhase { - protected AcPhase(){} + private AcPhase(){} - public AcPower Power { get; protected init; } + public Voltage Voltage { get; private init; } = null!; + public Current Current { get; private init; } = null!; + public AcPower Power { get; private init; } = null!; public static AcPhase FromVoltageCurrentPhi(Voltage voltageRms, Current currentRms, @@ -37,6 +40,6 @@ public record AcPhase : Bus Voltage = voltageRms, Power = AcPower.FromActiveReactiveApparent(activePower, reactivePower, apparentPower) }; - - + + public static AcPhase Null { get; } = FromVoltageCurrentPhi(0, 0, 0); } \ No newline at end of file diff --git a/csharp/Lib/Units/Composite/AcPower.cs b/csharp/Lib/Units/Composite/AcPower.cs index df5be0992..aacea2ced 100644 --- a/csharp/Lib/Units/Composite/AcPower.cs +++ b/csharp/Lib/Units/Composite/AcPower.cs @@ -1,16 +1,18 @@ +using InnovEnergy.Lib.Units.Power; using static System.Math; namespace InnovEnergy.Lib.Units.Composite; -public record AcPower + +public sealed class AcPower { - protected AcPower(){} - - public ApparentPower Apparent { get; protected init; } - public ActivePower Active { get; protected init; } - public ReactivePower Reactive { get; protected init; } - public Angle Phi { get; protected init; } - public Double CosPhi { get; protected init; } + private AcPower(){} + + public ApparentPower Apparent { get; private init; } = null!; + public ActivePower Active { get; private init; } = null!; + public ReactivePower Reactive { get; private init; } = null!; + public Angle Phi { get; private init; } = null!; + public Double CosPhi { get; private init; } public static AcPower FromActiveReactiveApparent(ActivePower activePower, ReactivePower reactivePower, ApparentPower apparentPower) { @@ -42,7 +44,7 @@ public record AcPower Reactive = q, Apparent = s, Phi = phi, - CosPhi = p/s, + CosPhi = Cos(phi), }; } @@ -64,7 +66,6 @@ public record AcPower }; } - public static AcPower SumOf(params AcPower[] phases) { var p = phases.Sum(l => l.Active.Value); @@ -82,4 +83,8 @@ public record AcPower CosPhi = Cos(phi.Value) }; } + + public static AcPower Null { get; } = FromVoltageCurrentPhi(0, 0, 0); + + public override String ToString() => Active.ToString(); // TODO: show all } \ No newline at end of file diff --git a/csharp/Lib/Units/Composite/Bus.cs b/csharp/Lib/Units/Composite/Bus.cs deleted file mode 100644 index 1f2f9867f..000000000 --- a/csharp/Lib/Units/Composite/Bus.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System.Diagnostics.CodeAnalysis; - -namespace InnovEnergy.Lib.Units.Composite; - -[SuppressMessage("ReSharper", "MemberCanBeProtected.Global")] - -public abstract record Bus -{ - public Voltage Voltage { get; protected init; } - public Current Current { get; protected init; } -} \ No newline at end of file diff --git a/csharp/Lib/Units/Composite/DcBus.cs b/csharp/Lib/Units/Composite/DcBus.cs index e0ea1c504..011f31655 100644 --- a/csharp/Lib/Units/Composite/DcBus.cs +++ b/csharp/Lib/Units/Composite/DcBus.cs @@ -1,10 +1,14 @@ +using InnovEnergy.Lib.Units.Power; + namespace InnovEnergy.Lib.Units.Composite; -public record DcBus : Bus +public sealed class DcBus { - protected DcBus() {} + private DcBus() {} - public ActivePower Power { get; protected init; } + public Voltage Voltage { get; private init; } = null!; + public Current Current { get; private init; } = null!; + public ActivePower Power { get; private init; } = null!; public static DcBus FromVoltageCurrent(Voltage voltage, Current current) => new() { @@ -12,4 +16,6 @@ public record DcBus : Bus Current = current, Power = current.Value * voltage.Value, }; + + public static DcBus Null { get; } = FromVoltageCurrent(0, 0); } \ No newline at end of file diff --git a/csharp/Lib/Units/Current.cs b/csharp/Lib/Units/Current.cs index db85db843..95c92d699 100644 --- a/csharp/Lib/Units/Current.cs +++ b/csharp/Lib/Units/Current.cs @@ -1,20 +1,13 @@ -using InnovEnergy.Lib.SrcGen; -using InnovEnergy.Lib.SrcGen.Attributes; - namespace InnovEnergy.Lib.Units; -[Generate][Generate] -public readonly partial struct Current +public sealed class Current : Unit { - public static String Unit => "A"; - public static String Symbol => "I"; + public override String Symbol => "A"; + public Current(Double value) : base(value) + {} - - // P=UI - public static ActivePower operator *(Current current, Voltage voltage) => new ActivePower(current.Value * voltage.Value); - - // U=RI - public static Voltage operator *(Current current, Resistance resistance) => new Voltage(resistance.Value* current.Value); - + public static implicit operator Current(Double d) => new Current(d); + public static implicit operator Double(Current d) => d.Value; + } \ No newline at end of file diff --git a/csharp/Lib/Units/DcPower.cs b/csharp/Lib/Units/DcPower.cs deleted file mode 100644 index d124d9f9e..000000000 --- a/csharp/Lib/Units/DcPower.cs +++ /dev/null @@ -1,22 +0,0 @@ -using InnovEnergy.Lib.SrcGen.Attributes; -using InnovEnergy.Lib.Time.Unix; - -namespace InnovEnergy.Lib.Units; - - -[Generate][Generate] -public readonly partial struct DcPower -{ - public static String Unit => "W"; - public static String Symbol => "P"; - - // P=UI - public static Voltage operator /(DcPower power, Current current) => new Voltage(power.Value / current.Value); - public static Current operator /(DcPower power, Voltage voltage) => new Current(power.Value / voltage.Value); - - public static Energy operator *(DcPower power, TimeSpan timeSpan) => power.Value / 1000 * timeSpan.TotalHours; - public static Energy operator *(TimeSpan timeSpan, DcPower power) => power.Value / 1000 * timeSpan.TotalHours; - - public static Energy operator *(DcPower power, UnixTimeSpan timeSpan) => power.Value * timeSpan.Ticks / 3_600_000; - public static Energy operator *(UnixTimeSpan timeSpan, DcPower power) => power.Value * timeSpan.Ticks / 3_600_000; -} \ No newline at end of file diff --git a/csharp/Lib/Units/Energy.cs b/csharp/Lib/Units/Energy.cs index 310591c93..0d5412244 100644 --- a/csharp/Lib/Units/Energy.cs +++ b/csharp/Lib/Units/Energy.cs @@ -1,15 +1,13 @@ -using InnovEnergy.Lib.SrcGen; -using InnovEnergy.Lib.SrcGen.Attributes; -using InnovEnergy.Lib.Time.Unix; - namespace InnovEnergy.Lib.Units; -[Generate][Generate] -public readonly partial struct Energy +public sealed class Energy : Unit { - public static String Unit => "kWh"; - public static String Symbol => "E"; + public override String Symbol => "kWh"; - public static ActivePower operator /(Energy energy, TimeSpan timeSpan) => energy.Value * 1000 / timeSpan.TotalHours ; - public static ActivePower operator /(Energy energy, UnixTimeSpan timeSpan) => energy.Value * 3_600_000 / timeSpan.Ticks; + public Energy(Double value) : base(value) + { + } + + public static implicit operator Energy(Double d) => new Energy(d); + public static implicit operator Double(Energy d) => d.Value; } \ No newline at end of file diff --git a/csharp/Lib/Units/Frequency.cs b/csharp/Lib/Units/Frequency.cs index f0a227c14..06671577a 100644 --- a/csharp/Lib/Units/Frequency.cs +++ b/csharp/Lib/Units/Frequency.cs @@ -1,19 +1,15 @@ -using InnovEnergy.Lib.SrcGen; -using InnovEnergy.Lib.SrcGen.Attributes; - namespace InnovEnergy.Lib.Units; -[Generate("HAS_CONSTRUCTOR")][Generate] -public readonly partial struct Frequency +public sealed class Frequency : Unit { - public static String Unit => "Hz"; - public static String Symbol => "f"; + public override String Symbol => "Hz"; - public Frequency(Double value) + public Frequency(Double value) : base(value) { if (value < 0) throw new ArgumentException(nameof(Frequency) + " cannot be negative", nameof(value)); - - Value = value; } + + public static implicit operator Frequency(Double d) => new Frequency(d); + public static implicit operator Double(Frequency d) => d.Value; } \ No newline at end of file diff --git a/csharp/Lib/Units/Percent.cs b/csharp/Lib/Units/Percent.cs index e239d2f92..01ad96f28 100644 --- a/csharp/Lib/Units/Percent.cs +++ b/csharp/Lib/Units/Percent.cs @@ -1,12 +1,13 @@ -using InnovEnergy.Lib.SrcGen; -using InnovEnergy.Lib.SrcGen.Attributes; - namespace InnovEnergy.Lib.Units; - -[Generate][Generate] -public readonly partial struct Percent +public sealed class Percent : Unit { - public static String Unit => "%"; - public static String Symbol => "%"; // ?? + public override String Symbol => "%"; + + public Percent(Double value) : base(value) + { + } + + public static implicit operator Percent(Double d) => new Percent(d); + public static implicit operator Double(Percent d) => d.Value; } \ No newline at end of file diff --git a/csharp/Lib/Units/Power/AcPower.cs b/csharp/Lib/Units/Power/AcPower.cs new file mode 100644 index 000000000..d1aadbc7f --- /dev/null +++ b/csharp/Lib/Units/Power/AcPower.cs @@ -0,0 +1,8 @@ +namespace InnovEnergy.Lib.Units.Power; + +public abstract class AcPower : Power +{ + protected AcPower(Double value) : base(value) + { + } +} \ No newline at end of file diff --git a/csharp/Lib/Units/Power/ActivePower.cs b/csharp/Lib/Units/Power/ActivePower.cs new file mode 100644 index 000000000..ab9d638c4 --- /dev/null +++ b/csharp/Lib/Units/Power/ActivePower.cs @@ -0,0 +1,15 @@ +namespace InnovEnergy.Lib.Units.Power; + + +public sealed class ActivePower : AcPower +{ + public override String Symbol => "W"; + + public ActivePower(Double value) : base(value) + { + } + + public static implicit operator ActivePower(Double d) => new ActivePower(d); + public static implicit operator Double(ActivePower d) => d.Value; +} + diff --git a/csharp/Lib/Units/Power/ApparentPower.cs b/csharp/Lib/Units/Power/ApparentPower.cs new file mode 100644 index 000000000..7704929ea --- /dev/null +++ b/csharp/Lib/Units/Power/ApparentPower.cs @@ -0,0 +1,14 @@ +namespace InnovEnergy.Lib.Units.Power; + +public sealed class ApparentPower : AcPower +{ + public override String Symbol => "VA"; + + public ApparentPower(Double value) : base(value) + { + } + + public static implicit operator ApparentPower(Double d) => new ApparentPower(d); + public static implicit operator Double(ApparentPower d) => d.Value; +} + diff --git a/csharp/Lib/Units/Power/DcPower.cs b/csharp/Lib/Units/Power/DcPower.cs new file mode 100644 index 000000000..b47bea512 --- /dev/null +++ b/csharp/Lib/Units/Power/DcPower.cs @@ -0,0 +1,13 @@ +namespace InnovEnergy.Lib.Units.Power; + +public sealed class DcPower : AcPower +{ + public override String Symbol => "W"; + + public DcPower(Double value) : base(value) + { + } + + public static implicit operator DcPower(Double d) => new DcPower(d); + public static implicit operator Double(DcPower d) => d.Value; +} diff --git a/csharp/Lib/Units/Power/Power.cs b/csharp/Lib/Units/Power/Power.cs new file mode 100644 index 000000000..6fa225535 --- /dev/null +++ b/csharp/Lib/Units/Power/Power.cs @@ -0,0 +1,9 @@ +namespace InnovEnergy.Lib.Units.Power; + +public abstract class Power : Unit +{ + protected Power(Double value) : base(value) + { + } + +} \ No newline at end of file diff --git a/csharp/Lib/Units/Power/ReactivePower.cs b/csharp/Lib/Units/Power/ReactivePower.cs new file mode 100644 index 000000000..28238d62a --- /dev/null +++ b/csharp/Lib/Units/Power/ReactivePower.cs @@ -0,0 +1,14 @@ +namespace InnovEnergy.Lib.Units.Power; + +public sealed class ReactivePower : AcPower +{ + public override String Symbol => "var"; + + public ReactivePower(Double value) : base(value) + { + } + + public static implicit operator ReactivePower(Double d) => new ReactivePower(d); + public static implicit operator Double(ReactivePower d) => d.Value; +} + diff --git a/csharp/Lib/Units/ReactivePower.cs b/csharp/Lib/Units/ReactivePower.cs deleted file mode 100644 index c8de6fe0e..000000000 --- a/csharp/Lib/Units/ReactivePower.cs +++ /dev/null @@ -1,12 +0,0 @@ -using InnovEnergy.Lib.SrcGen; -using InnovEnergy.Lib.SrcGen.Attributes; - -namespace InnovEnergy.Lib.Units; - -[Generate][Generate] -public readonly partial struct ReactivePower -{ - public static String Unit => "var"; - public static String Symbol => "Q"; - -} \ No newline at end of file diff --git a/csharp/Lib/Units/Resistance.cs b/csharp/Lib/Units/Resistance.cs index a9925c60e..6fb132a72 100644 --- a/csharp/Lib/Units/Resistance.cs +++ b/csharp/Lib/Units/Resistance.cs @@ -1,16 +1,13 @@ -using InnovEnergy.Lib.SrcGen; -using InnovEnergy.Lib.SrcGen.Attributes; - namespace InnovEnergy.Lib.Units; - -[Generate][Generate] -public readonly partial struct Resistance +public sealed class Resistance: Unit { - public static String Unit => "Ω"; - public static String Symbol => "R"; - - // // U=RI - // public static Voltage operator *(Resistance resistance, Current current) => new Voltage(resistance.Value * current.Value); - + public override String Symbol => "Ω"; + + public Resistance(Double value) : base(value) + { + } + + public static implicit operator Resistance(Double d) => new Resistance(d); + public static implicit operator Double(Resistance d) => d.Value; } \ No newline at end of file diff --git a/csharp/Lib/Units/Temperature.cs b/csharp/Lib/Units/Temperature.cs index cff28e2e5..102e378e0 100644 --- a/csharp/Lib/Units/Temperature.cs +++ b/csharp/Lib/Units/Temperature.cs @@ -1,13 +1,11 @@ - -using InnovEnergy.Lib.SrcGen; -using InnovEnergy.Lib.SrcGen.Attributes; - namespace InnovEnergy.Lib.Units; - -[Generate][Generate] -public readonly partial struct Temperature +public sealed class Temperature : Unit { - public static String Unit => "°C"; - public static String Symbol => "T"; + public override String Symbol => "°C"; + + public Temperature(Double value) : base(value){} + + public static implicit operator Temperature(Double d) => new Temperature(d); + public static implicit operator Double(Temperature d) => d.Value; } \ No newline at end of file diff --git a/csharp/Lib/Units/Unit.cs b/csharp/Lib/Units/Unit.cs new file mode 100644 index 000000000..e30787060 --- /dev/null +++ b/csharp/Lib/Units/Unit.cs @@ -0,0 +1,11 @@ +namespace InnovEnergy.Lib.Units; + +public abstract class Unit +{ + protected Unit(Double value) => Value = value; + + public abstract String Symbol { get; } + public Double Value { get; } + + public override String ToString() => $"{Value} {Symbol}"; +} \ No newline at end of file diff --git a/csharp/Lib/Units/Units.cs b/csharp/Lib/Units/Units.cs index 36a55b93f..8d07d3bb6 100644 --- a/csharp/Lib/Units/Units.cs +++ b/csharp/Lib/Units/Units.cs @@ -1,3 +1,9 @@ +using System.Collections; +using System.Reflection; +using InnovEnergy.Lib.Units.Power; +using InnovEnergy.Lib.Utils; +using static System.Reflection.BindingFlags; + namespace InnovEnergy.Lib.Units; public static class Units @@ -16,30 +22,69 @@ public static class Units public static Temperature Celsius(this Double value) => value; public static Energy KWh (this Double value) => value; - - public static String ToCsv(this T thing) + public static String ToCsv(this Object thing) { - IEnumerable GetChildren(Object parent) + var csvLines = new List(); + var visited = new HashSet(); + + GetCsv(thing); + + return csvLines.JoinLines(); + + void GetCsv(Object? parent, String path = "") { + if (parent == null) + return; + var type = parent.GetType(); + + if (parent is Unit u) + { + csvLines.Add($"{path};{u.Value};{u.Symbol}"); // leaf: unit + } + else if (parent is String s) + { + csvLines.Add($"{path};{s};"); // leaf: unit + } + else if(type.IsEnum || (type.IsValueType && !type.IsNested)) + { + csvLines.Add($"{path};{parent};"); // leaf: value type + } + else if (parent is IEnumerable enumerable) + { + var enumerableType = enumerable.GetType(); - parent - .GetType() - .GetProperties(); + var elementType = enumerableType.GetGenericArguments().SingleOrDefault() ?? + enumerableType.GetElementType(); // for arrays + + if (elementType is null) + return; + + if (elementType.IsValueType || elementType == typeof(String)) + { + var value = enumerable.Cast().JoinWith(","); + csvLines.Add($"{path};{value};"); + } + else + { + var i = 1; + foreach (var o in enumerable) + GetCsv(o, $"{path}/{i++}"); + } + } + else + { + if (!visited.Add(parent)) + return; + foreach (var p in type.GetProperties(Instance | Public)) + { + var name = p.Name; + var value = p.GetValue(parent); + GetCsv(value, $"{path}/{name}"); + } + } } - - - thing.TraverseLeavesWithPath() - if (thing is null) - return new Dictionary(); - - return thing - .GetType() - .GetProperties() - .Select(p => (p.Name, Value: p.GetValue(thing)?.ToString())) - .Where(p => p.Value != null) - .ToDictionary(p => p.Name, p=>p.Value!); } } @@ -126,4 +171,4 @@ public static class Prefixes return $"{r*s} {lookUp[Math.Abs(i)]}{unit}"; } -} \ No newline at end of file +} diff --git a/csharp/Lib/Units/Voltage.cs b/csharp/Lib/Units/Voltage.cs index bf6cb9fd9..49a33342c 100644 --- a/csharp/Lib/Units/Voltage.cs +++ b/csharp/Lib/Units/Voltage.cs @@ -1,18 +1,13 @@ -using InnovEnergy.Lib.SrcGen; -using InnovEnergy.Lib.SrcGen.Attributes; namespace InnovEnergy.Lib.Units; - -[Generate][Generate] -public readonly partial struct Voltage +public sealed class Voltage : Unit { - public static String Unit => "V"; - public static String Symbol => "U"; + public override String Symbol => "V"; + + public Voltage(Double value) : base(value) + {} - // U=RI - public static Current operator /(Voltage voltage, Resistance resistance) => new Current(voltage.Value / resistance.Value); - - // P=UI - public static ActivePower operator *(Voltage voltage, Current current) => new ActivePower(current.Value * voltage.Value); + public static implicit operator Voltage(Double d) => new Voltage(d); + public static implicit operator Double(Voltage d) => d.Value; } \ No newline at end of file