C # Шаблон посетителя Выражения для построения результата Единица измерения - PullRequest
2 голосов
/ 01 июля 2011

Я приступаю к проекту, включающему некоторые расчеты, и начал с довольно простой адаптации UOM (Единицы измерения) на основе структуры Cureos. Пока все хорошо, у меня есть несколько базовых единиц.

Одна из вещей, которые я хотел бы сделать, - это построить фундаментальные единицы, чтобы получить расчетные значения. Например, если у нас есть Длина (или Расстояние ) и Время , мы можем получить Скорость (Расстояние / Время) или Ускорение (Расстояние / Квадрат (Время)).

Мои юниты гибки; Я могу показать их как на английском языке, на языке СИ, так и на любой другой системе, которая должна быть в нужном количестве, футах, дюймах, метрах, сантиметрах и т. Д. Или в случае времени, миллисекунд, секунд, минут и т. Д. 1015 *

Что я хотел бы сделать, так это сообщить фактическую единицу измерения на момент расчета. Поэтому, если единицы измерения - метры и секунды, я бы хотел сообщить «м / с» для скорости или «м / с ^ 2» для ускорения. Или, если используются единицы измерения: футы и миллисекунды, укажите «фут / мс» или «фут / мс ^ 2» соответственно.

Итак ... С этой историей я развлекаюсь возможностью выразить эти более сложные единицы (если хотите, может быть, это единица, может быть, это не ... это TBD) как Выражение Linq Деревья , с помощью которых я мог бы правдоподобно посещать узлы во всем Дереве выражений для своих единиц и «компилировать» имена единиц только в дополнение к фактическому числовому результату.

Если задействованные объекты - это Меры (для количественных значений), Единицы (для единиц) и Количества (для вида единиц), мне кажется, это должно быть вполне выполнимо.

Мысли

1 Ответ

1 голос
/ 01 июля 2011

Я не уверен, что вы просите здесь, но когда я столкнулся с проблемой поддержания единиц различных переменных в моей программе и поиска правильных единиц результирующего значения, это решение, которое я придумал.

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;
        }
    }
}

Это позволит вам определить операторы на единицах, которые возвращают другие единицы (простая математика MLT).Обратите внимание, что S на самом деле является S ^ 2 и является наиболее читабельным способом, который я придумал для реализации этой функции.

Надеюсь, это поможет!

...