开发者

C# Visitor pattern Expressions to build result Unit of measure

I am embarking on a project involving some calculations and have started with a fairly straightforward UOM (Unit of Measurement) adaptation based on the Cureos framework. So far so good, I've got some basic Units represented.

One of the things I would like to do is to build upon the foundational units in order to arrive at calculated values. For insta开发者_开发问答nce, if we have Length (or Distance) and Time, we can arrive at Velocity (Distance / Time) or Acceleration (Distance / Square(Time)).

My units are flexible; I can show them as either English, SI, or whatever the system happens to be in whatever quantity I need, whether feet, inches, meters, centimeters, etc. Or in the case of time, milliseconds, seconds, minutes, etc.

What I'd like to do is report the actual unit at the moment of calculation. So if the units are meters and seconds, I'd like to report "m/s" for Velocity or "m/s^2" for Acceleration. Or, if the units are feet and milliseconds, report "ft/ms" or "ft/ms^2", respectively.

So... With that story as the backdrop, I am entertaining the possibility of expressing these more complex units (if you will, maybe it's a unit, maybe it's not... that's TBD) as Linq Expression Trees whereby I could plausibly visit the nodes throughout the Expression Tree for its units and "compile" the unit names just in addition to the actual numeric result.

If the objects involved are Measures (for quantifiable values), Units (for the units) and Quantities (for the kind of unit), it seems to me this should be quite doable.

Thoughts?


I'm not sure what you're asking for here, but when confronted with the problem of maintaining units of different variables in my program and finding the correct units of the resultant value, this is the solution I came up with.

using System;

namespace ConsoleApplication1
{
    public interface Mass
    {
    }

    public class Kg: Mass
    {
    }

    public interface Length
    {
    }

    public interface M : Length
    {
    }

    public interface M<in T>: M where T: M, Length
    {
    }

    public interface Time
    {
    }

    public interface S : Time
    {
    }

    public interface S<in T> : S where T : S, Time
    {
    }

    public interface IUnit<in M, in L, in T> 
        where M: Mass 
        where L: Length
        where T: Time
    {
    }

    public sealed class Unit<M, L, T>: IUnit<M, L, T>
        where M : Mass
        where L : Length
        where T : Time
    {
        public static Unit<M, L, T>  operator +(Unit<M, L, T> a, Unit<M, L, T> b)
        {
            throw new NotImplementedException();
        }
    }

    public interface Nil: Mass, Length, Time
    {
    }

    class Program
    {
        static void Main(string[] args)
        {
            Unit<Nil, M, S<S>> value1 = null;
            Unit<Nil, M, S<S>> value2 = null;

            var result = value1 + value2;
        }
    }
}

This would allow you to define operators on units which return other units (simple MLT math). Note that the S is actually S^2 and is the most readable way I came up with to implement this feature.

Hope this helps!

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜