@@ -724,6 +724,43 @@ private static string BuildToBaseExpression(string unitName, Dictionary<string,
724724 return scaled ;
725725 }
726726
727+ /// <summary>
728+ /// Adds the per-quantity surface required by <see cref="ktsu.Semantics.Quantities.IPhysicalQuantity{T}"/>
729+ /// (#59): a <c>Dimension</c> override returning <c>PhysicalDimensions.{dim}</c>, plus a
730+ /// typed <c>In(I{dim}Unit)</c> method that converts the stored SI-base value into the
731+ /// caller's unit. Emitted for V0 and V1 (scalar-storage) types only; vector V2+ types
732+ /// have per-component conversion needs and are deferred.
733+ /// </summary>
734+ private static void AddDimensionAndInMembers ( ClassTemplate cls , PhysicalDimension dim )
735+ {
736+ cls . Members . Add ( new FieldTemplate ( )
737+ {
738+ Comments = [ $ "/// <summary>Gets the physical dimension this quantity belongs to.</summary>"] ,
739+ Keywords = [ "public" , "override" , "DimensionInfo" ] ,
740+ Name = $ "Dimension => PhysicalDimensions.{ dim . Name } ",
741+ } ) ;
742+
743+ cls . Members . Add ( new MethodTemplate ( )
744+ {
745+ Comments =
746+ [
747+ "/// <summary>" ,
748+ $ "/// Converts this quantity's SI-base value to the value in <paramref name=\" unit\" />.",
749+ "/// Cross-dimension calls (e.g. passing a non-" + dim . Name + " unit) fail at compile time." ,
750+ "/// </summary>" ,
751+ "/// <param name=\" unit\" >The dimensionally-compatible target unit.</param>" ,
752+ "/// <returns>The value expressed in <paramref name=\" unit\" />.</returns>" ,
753+ ] ,
754+ Keywords = [ "public" , "T" ] ,
755+ Name = "In" ,
756+ Parameters =
757+ [
758+ new ParameterTemplate { Type = $ "global::ktsu.Semantics.Quantities.I{ dim . Name } Unit", Name = "unit" } ,
759+ ] ,
760+ BodyFactory = ( body ) => body . Write ( " => unit.FromBase(Value);" ) ,
761+ } ) ;
762+ }
763+
727764 private static Dictionary < string , List < T > > GroupBy < T > ( List < T > items , Func < T , string > keySelector )
728765 {
729766 Dictionary < string , List < T > > groups = [ ] ;
@@ -803,6 +840,9 @@ private void EmitV0BaseType(
803840 "<see cref=\" " + typeName + "{T}\" />" ,
804841 applyV0Guard : true ) ;
805842
843+ // Dimension override + typed In() (#59).
844+ AddDimensionAndInMembers ( cls , dim ) ;
845+
806846 // V0 - V0 returns the same V0 of T.Abs(left - right) (locked decision in #52).
807847 // We emit this on every V0 base type so the derived operator wins overload resolution
808848 // over PhysicalQuantity's plain subtraction (which can produce a negative magnitude
@@ -892,6 +932,9 @@ private void EmitV1BaseType(
892932 "<see cref=\" " + typeName + "{T}\" />" ,
893933 applyV0Guard : false ) ;
894934
935+ // Dimension override + typed In() (#59).
936+ AddDimensionAndInMembers ( cls , dim ) ;
937+
895938 // Magnitude method returning V0 base
896939 if ( v0TypeName != null )
897940 {
@@ -1080,6 +1123,9 @@ private void EmitOverloadType(
10801123 applyV0Guard : vectorForm == 0 ,
10811124 strictPositive : strictPositive ) ;
10821125
1126+ // Dimension override + typed In() (#59).
1127+ AddDimensionAndInMembers ( cls , dim ) ;
1128+
10831129 // Implicit widening to base type
10841130 cls . Members . Add ( new MethodTemplate ( )
10851131 {
0 commit comments