Пользовательские формулы в C #

2

У меня есть приложение, где для каждого объекта пользователь может указать свои собственные измерительные точки. Значения этих измерений затем будут использоваться для классификации объекта как службы i-A, требуется B-обслуживание в течение X дней, C - нет необходимости в обслуживании ATM

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

Есть ли у вас какие-либо предложения о том, как мы можем предоставить пользователю возможность вводить его собственные формулы? Это не должно быть идиот-доказательством, у нас не так много клиентов, поэтому мы можем помочь им, пока они могут объяснить это нам.

  • 1
    Можете ли вы объяснить проблему немного больше?
  • 0
    Может ли это быть достигнуто, позволяя пользователю определять пределы значений, которые будут помечать объект как категорию 1,2 или 3? Или у объектов вообще разные свойства?
Показать ещё 1 комментарий
Теги:
eval

7 ответов

1
Лучший ответ

Оценщик выражения экспрессии

Вы можете предоставить пользователям список переменных, которые действительны для использования, и позволить им придумывать свои собственные выражения. Затем вы передадите все выражения, имена переменных и значения в Flee, и он разрешит все выражения для значения или true/false.

  • 0
    Это выглядит как действительно хороший вариант для меня. Thanx!
  • 0
    Вы также можете посмотреть на lundin.info , который делает нечто подобное.
Показать ещё 1 комментарий
1

Я написал проект с открытым исходным кодом Dynamic Expresso, который может преобразовывать текстовое выражение, написанное с использованием синтаксиса С#, в делегаты (или дерево выражений), Выражения анализируются и преобразуются в Деревья выражений без использования компиляции или отражения.

Вы можете написать что-то вроде:

var interpreter = new Interpreter();
var result = interpreter.Eval("8 / 2 + 2");

или

var interpreter = new Interpreter()
                .SetVariable("service", new ServiceExample());

string expression = "x > 4 ? service.SomeMethod() : service.AnotherMethod()";

Lambda parsedExpression = interpreter.Parse(expression, 
                        new Parameter("x", typeof(int)));

parsedExpression.Invoke(5);

Моя работа основана на статье Скотта Гуа http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx.

1

Ваша ситуация - идеальный вариант для языка, специфичного для домена. DSL позволит вам указать допустимую грамматику для вашего "языка формул", а затем предоставить обратную связь пользователю, а также рассчитать результат.

Antlr - очень хороший инструмент для этого. Это генератор парсера/лексара. В основном вы указываете грамматику в собственном описании DSL Antlr, и она генерирует надежные лексеры и синтаксические анализаторы для вас на выбранном вами языке.

Например, если ваш язык допускает простые вычисления, так это будет указано в языке antlr (из antlr wiki):

grammar SimpleCalc;

options {
    language=CSharp2;
}

tokens {
    PLUS    = '+' ;
    MINUS   = '-' ;
    MULT    = '*' ;
    DIV = '/' ;
}

@members {
    public static void Main(string[] args) {
        SimpleCalcLexer lex = new SimpleCalcLexer(new ANTLRFileStream(args[0]));
        CommonTokenStream tokens = new CommonTokenStream(lex);

        SimpleCalcParser parser = new SimpleCalcParser(tokens);

        try {
            parser.expr();
        } catch (RecognitionException e)  {
            Console.Error.WriteLine(e.StackTrace);
        }
    }
}

/*------------------------------------------------------------------
 * PARSER RULES
 *------------------------------------------------------------------*/

expr    : term ( ( PLUS | MINUS )  term )* ;

term    : factor ( ( MULT | DIV ) factor )* ;

factor  : NUMBER ;


/*------------------------------------------------------------------
 * LEXER RULES
 *------------------------------------------------------------------*/

NUMBER  : (DIGIT)+ ;

WHITESPACE : ( '\t' | ' ' | '\r' | '\n'| '\u000C' )+    { $channel = HIDDEN; } ;

fragment DIGIT  : '0'..'9' ;

Вы можете узнать больше о DSL вообще здесь.

  • 0
    Хорошее предложение, но я думаю, что Flee предоставляет все, что мне нужно, с меньшим количеством строк кода, чем этот.
1

SpreadsheetGear для .NET может быть хорошим выбором. SpreadsheetGear принимает и вычисляет формулы на языке, который большинство пользователей уже знают - Excel. SpreadsheetGear включает в себя элемент управления электронной таблицей Windows Forms, или вы можете использовать его в качестве библиотеки, если вы делаете ASP.NET или веб-службу.

Вы можете увидеть простые примеры расчета ASP.NET здесь или загрузить бесплатную пробную версию здесь, если вы хотите попробовать элемент управления WinForms.

Отказ от ответственности: у меня есть SpreadsheetGear LLC

  • 0
    Хотя я опубликовал ответ о DSL, я полностью поддерживаю и использую механизм электронных таблиц Джо. Это отличный продукт.
  • 0
    Вероятно, это был бы мой выбор, если бы пользователь, который собирался создавать формулы, не был человеком с хорошими навыками программирования, однако в данный момент я не вижу ситуации, когда мы позволим реальному конечному пользователю настроить это так сложнее ( и бесплатно) решение не проблема. Но продукт выглядит великолепно, и я буду помнить это для будущих продуктов.
0

Вы упомянули, что объекты могут быть "почти любыми". Может ли мера также быть почти чем угодно? Предположительно, измерения будут ограничены определенными свойствами объекта, о котором идет речь, и в этом случае вы, вероятно, можете открыть редактор, похожий на мастера, который позволит пользователю выполнять вычисления на основе свойств объектов, обнаруженных с помощью отражения. Одна вещь, которую вы делаете для вас путем ограничения проблемы, состоит в том, что вы, похоже, применяете 3 конечных точки для измерения вместо 1-го состояния.

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

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

Кроме того, знаете ли вы, как вы будете опросить объекты для вычисления измерений, чтобы определить состояние объектов?

Извините, что говоришь так вообще, но на самом деле в этот момент ваш вопрос довольно общий. Удачи.

  • 0
    Мне нужно быть более конкретным в моих вопросах :) Вы дали меду некоторые соображения, но я думаю, что нашел свое решение в Flee.
0

Вы должны использовать выражения .NET 3.5 в System.Linq.Expressions. Скотт Гу предоставил API динамического выражения, который позволяет вам оценивать строки, чтобы превратить их в деревья выражений, которые затем могут быть оценены кодом либо для проверки содержимого выражения, либо скомпилированы для выполнения.

http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx

0

Может ли пользователь использовать свои знания об объекте и просто решить, какую категорию включить, когда он войдет в систему? Угадайте, нам нужна дополнительная информация, но если пользователь может определить, какие измерения определяют, какую категорию, не могли они просто выбрать категорию?

Ещё вопросы

Сообщество Overcoder
Наверх
Меню