Related
This question already has answers here:
Why does is operator behave like == operator?
(3 answers)
Using "is" keyword with "null" keyword c# 7.0
(2 answers)
Closed 2 years ago.
I was teaching my students how to write a function. I used a simple algorithm to determine if a char value is an actual letter (and not a digit or something else).
So I actually typed what my student said (playing dumb on purpose): "if (letter is 'A') {...}"
To my surprise this didn't cause a compiler error. I added the same check for 'B' and 'C' and my program can now determine that A, B and C are indeed letters.
Why does that work? And WHAT exactly am I comparing here?
I'm not actively using type comparisons, which is what the internet keeps turning up.
I did an additional experiment with other values:
char l = 'A';
if (l is 'A')
{
Console.WriteLine("l 'A'...");
}
if (l is "A")
{
// Doesn't compile.
}
int x = 15;
if (x is 15)
{
Console.WriteLine("X is 15.");
}
if (x is 5.6)
{
// Also doesn't compile.
}
As far as I can tell "is" functions as an extended version of the equality (==) operator that also enforces the same type. But I can't find any documentation on it.
is might have two meanings, depending on which version of C# you have.
In older C# versions, is was short for "is assignable to" or "is assignable from", depending on how you read the code in your head. It wouldn't work for the code in your class because it expects a type on the right-hand side, but I include it here for completeness. It's also useful as an efficient and portable null check, ie variable is object is a better way to write variable != null1.
In newer C# versions, is can also be used for pattern matching. This was introduced in C# 72 and extended in C# 8, with more coming in 9. Specifically, the code in the question creates a Constant Pattern expression.
Here's another fun way to see this work. Coming in C# 9, instead of writing a check like this:
if (!string.IsNullOrEmpty(mystring))
You could instead write3
if (mystring is {Length:>0})
Which is nice because it's shorter and you could make an argument removing the negation makes it easier to understand.4
At least, according to one of the developers on the C# team at Microsoft. But what would he know? He only built the thing.
Really, C# 6 if you count exception filters.
Jared Parsons again.
I'd reject that argument on the grounds any gains in removing the negation are less than the subtlety introduced in how we validate for null. But you could try the argument ;) And before anyone asks, I have no idea at this time how the two options perform.
I need to locate a fast, lightweight expression parser.
Ideally I want to pass it a list of name/value pairs (e.g. variables) and a string containing the expression to evaluate. All I need back from it is a true/false value.
The types of expressions should be along the lines of:
varA == "xyz" and varB==123
Basically, just a simple logic engine whose expression is provided at runtime.
UPDATE
At minimum it needs to support ==, !=, >, >=, <, <=
Regarding speed, I expect roughly 5 expressions to be executed per request. We'll see somewhere in the vicinity of 100/requests a second. Our current pages tend to execute in under 50ms. Usually there will only be 2 or 3 variables involved in any expression. However, I'll need to load approximately 30 into the parser prior to execution.
UPDATE 2012/11/5
Update about performance. We implemented nCalc nearly 2 years ago. Since then we've expanded it's use such that we average 40+ expressions covering 300+ variables on post backs. There are now thousands of post backs occurring per second with absolutely zero performance degradation.
We've also extended it to include a handful of additional functions, again with no performance loss. In short, nCalc met all of our needs and exceeded our expectations.
Have you seen https://ncalc.codeplex.com/ and https://github.com/sheetsync/NCalc ?
It's extensible, fast (e.g. has its own cache) enables you to provide custom functions and varaibles at run time by handling EvaluateFunction/EvaluateParameter events. Example expressions it can parse:
Expression e = new Expression("Round(Pow(Pi, 2) + Pow([Pi2], 2) + X, 2)");
e.Parameters["Pi2"] = new Expression("Pi * Pi");
e.Parameters["X"] = 10;
e.EvaluateParameter += delegate(string name, ParameterArgs args)
{
if (name == "Pi")
args.Result = 3.14;
};
Debug.Assert(117.07 == e.Evaluate());
It also handles unicode & many data type natively. It comes with an antler file if you want to change the grammer. There is also a fork which supports MEF to load new functions.
It also supports logical operators, date/time's strings and if statements.
How about the Fast Lightweight Expression Evaluator? It lets you set variables and supports logical operators.
If you need something beefier and have the time, you could also design your own expression language with Irony.
Hisystems' Interpreter supports custom functions, operators and literals, is lightweight pure c# portable code. Currently runs on iOS via MonoTouch and should run on any other Mono environment as well as windows. Free for commercial use. Available on GitHub at https://github.com/hisystems/Interpreter.
I fully appreciate how late this answer is however I would like to throw in my solution because I believe it can add more above the accepted answer of using NCalc should someone wish to use the expressions across multiple platforms.
-- Update --
I have created a parser for C# with plans to also implement it for Java and Swift over the next few months. This would mean that you can evaluate the expressions on multi-platforms without the need for tweaking per platform.
While Java and Swift was planned it never made it in to a fully fledge release. Instead there is now support for .NET Standard enabling support for Xamarin apps.
-- End update --
Expressive is the tool and it is available at:
GitHub or Nuget.
The site has a fair amount of documentation on it but to prevent link rot here is an example on how to use it:
Variable support
var expression = new Expression("1 * [variable]");
var result = expression.Evaluate(new Dictionary<string, object> { ["variable"] = 2);
Functions
var expression = new Expression("sum(1,2,3,4)");
var result = expression.Evaluate();
It was designed to match NCalc as best as possible however it has added support for things like a 'null' keyword.
self promotion here
i wrote aa generic parser generator for c# https://github.com/b3b00/csly
you can find an expression parseras example on my github. you may need to customize it to fit your needs
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
I need a fast runtime expression parser
How do I make it that when someone types in x*y^z in a textbox on my page to calculate that equation in the code behind and get the result?
.NET does not have a built-in function for evaluating arbitrary strings. However, an open source .NET library named NCalc does.
NCalc is a mathematical expressions evaluator in .NET. NCalc can parse
any expression and evaluate the result, including static or dynamic
parameters and custom functions.
Answer from operators as strings by user https://stackoverflow.com/users/1670022/matt-crouch, using built-in .NET functionality:
"If all you need is simple arithmetic, do this.
DataTable temp = new DataTable();
Console.WriteLine(temp.Compute("15 / 3",string.Empty));
EDIT: a little more information. Check out the MSDN documentation for the Expression property of the System.Data.DataColumn class. The stuff on "Expression Syntax" outlines a list of commands you can use in addition to the arithmetic operators. (ex. IIF, LEN, etc.)."
EDIT 2: For convenience, you can put this into a little function like:
public string Eval(string expr)
{
var temp = new System.Data.DataTable();
string result = null;
try
{
result = $"{temp.Compute(expr, string.Empty)}";
}
catch (System.Data.EvaluateException ex)
{
if (ex.Message.ToLower().Contains("cannot find column"))
throw new System.Data.SyntaxErrorException($"Syntax error: Invalid expression: '{expr}'."
+ " Variables as operands are not supported.");
else
throw;
}
return result;
}
So you can use it like:
Console.WriteLine(Eval("15 * (3 + 5) / (7 - 2)"));
giving the expected output:
24
Note that the error handler helps to handle exceptions caused by using variables which are not allowed here. Example: Eval("a") - Instead of returning "Cannot find column [a]", which doesn't make much sense in this context (we're not using it in a database context) it is returning "Syntax error: Invalid expression: 'a'. Variables as operands are not supported."
Run it on DotNetFiddle
There are two main approaches to this problem, each with some variations, as illustrated in the variety of answers.
Option A: Find an existing mathematical expresssion evaluator
Option B: Write your own parser and the logic to compute the result
Before going into some details about this, it is appropriate to stress that interpreting arbitrary mathematical expressions is not a trivial task, for any expression grammar other than "toy" grammars such as these that only accept one or two arithmetic operations and do not allow parenthesis etc.
Understanding that such task is deceivingly trivial, and acknowledging that, after all, interpreting arithmetic expressions of average complexity is a relatively recurrent need for various applications [hence one for which mature solutions should be available], it is probably wise to try and make do with "Option A".
I'd therefore second Jed's recommendation of a ready-make expression evaluator such as NCalc.
It may be useful however to take the time and understand the various concepts and methods associated with parsing and interpreting arithmetic expressions, as if one were going to whip-up one's own implementation.
The key concept is that of a formal grammar. The arithmetic expressions which the evaluator will accept must follow a set of rules such as the list of arithmetic operations allowed. For example will the evaluator support, say, trigonometric functions, or if it does, will this also include say atan2(). The rules also indicate what consitutes an operand, for example will it be allowed to input numerical values as big as say 45 digits. etc. The point is that all these rules are formalized in a grammar.
Typically a grammar works on tokens which have previously been extracted from the raw input text. Essentially at some time in the process, some logic needs to analyze the input string, character by character, and determine which sequences of characters go together. For example in the 123 + 45 / 9.3 expression, the tokens are the integer value 123, the plus operator, the integer value 45, the division operator and finally the 9.3 real value. The task of identifying the tokens and associating them with a token type is the job a lexer. Lexers can be build themselves on a grammar (a grammar which "tokens" are single characters, as opposed to the grammar for the arithmetic expression parser which tokens are short strings produced by the lexer.)
BTW, grammars are used to define many other things beyond arithmetic expressions. Computer languages follow [rather sophiticated] grammars, but it is relatively common to introduce Domain Specific Languages aka DSLs in support of various features of computer applications.
For very simple grammars, one may be able to write the corresponding lexer and parser from scratch. But sooner than later the grammars may get complicated to the point that hand-writing these modules becomes fastidious, bug-prone and maybe more importantly difficult to read. Hence the existence of Lexer and Parser Generators which are stand-alone programs that produce the code of lexers and parsers (in a particular programming language such as C, Java or C#) from a list of rules (expressed in a syntax particular to the generator, though many generators tend to use similar syntaxes, loosely base on BNF).
When using such a lexer/parser generator, work in done in multiple steps:
- first one writes a definition of the grammar (in the generator-specific language/syntax)
- one runs this grammar through the generator.
- one often repeats the above two steps multiple times, because writing a grammar is an exacting exercise: the generator will complain of many possible ambiguities one may write into the grammar.
- eventually the generator produces a source file (in the desired target language such as C# etc.)
- this source is included in the overall project
- other source files in the project may invoke the functions exposed in the source files produced by the generator and/or some logic corresponding to various patterns identified during parsing may readily be may imbedded in the generator produced code.
- the project can then be build as usual, i.e. as if the parser and lexer had be hand-written.
And that's about it for a 20,000 feet high presentation of the process of working with formal grammars and code generators.
A list of parser-generators (aka compiler-compilers) can be found at this link. For simple work in C# I also want to mention Irony. It may be very insightful to peruse these sites, to get a better feel for these concept, even without the intent of becoming a practitioner at this time.
As said, I wish to stress that for this particular application, a ready-made arithmetic evaluator is likely the better approach. The main downside of these would be
some limitations as to what the allowed expression syntax is (either the grammar allowed is too restrictive: you also need say stddev() or is too broad: you don't want your users to use trig functions. With the more mature evaluators, there will be some form of configuration/extension feature which allows dealing with this problem.
the learning curve of such a 3rd party module. Hopefully many of them should be relatively "plug-and-play".
solved with this library http://www.codeproject.com/Articles/21137/Inside-the-Mathematical-Expressions-Evaluator
my final code
Calculator Cal = new Calculator();
txt_LambdaNoot.Text = (Cal.Evaluate(txt_C.Text) / fo).ToString();
now when some one type 3*10^11 he will get 300000000000
You will need to implement (or find a third-party source) an expression parser. This is not a trivial thing to do.
What you need - if you want to do it yourself - is a Scanner (also known as Lexer) + Parser in the code behind which interprets the expression. Alternatively, you can find a 3rd party library which does the job and works similar as the JavaScript eval(string) function does.
Please take a look here, it describes an recursive descent parser. The example is written in C, but you should be able to adapt it to C# easily once you got the idea described in the article.
It is less complicated than it sounds, especially if you have a limited amount of operators to support.
The advantage is that you keep full control on what expressions will be executed (to prevent malicious code injections by the end-user of your website).
I'm a C# newbie. I want to write a calculator app in C#. Would C# expression trees be a good way to go for the guts of it? (That is, the part that takes a series of keypresses and turns them into an expression that the calculator can evaluate and display on the screen . . . or graph.)
I'll want to include the standard math functions, including trig, logs, exponents, etc.
Since your language for mathematical expressions will surely be much, much simpler than C#, I suspect that trying to reuse the framework expression tree classes to represent your ASTs will be overkill and probably a recipe for frustration; if you look at those classes, you'll see a lot of properties and functionality that would be totally irrelevant to your little language. I'd roll your own if I were you.
you might be able to learn from this project, there are good tutorials aobut how it was made
Have you seen http://ncalc.codeplex.com ?
It's extensible, fast (e.g. has its own cache) enables you to provide custom functions and varaibles at run time by handling EvaluateFunction/EvaluateParameter events. Example expressions it can parse:
Expression e = new Expression("Round(Pow(Pi, 2) + Pow([Pi2], 2) + X, 2)");
e.Parameters["Pi2"] = new Expression("Pi * Pi");
e.Parameters["X"] = 10;
e.EvaluateParameter += delegate(string name, ParameterArgs args)
{
if (name == "Pi")
args.Result = 3.14;
};
Debug.Assert(117.07 == e.Evaluate());
It also handles unicode & many data type natively. It comes with an antler file if you want to change the grammer. There is also a fork which supports MEF to load new functions.
It also supports logical operators, date/time's strings and if statements.
Note: Mathematical expression evaluation is not the focus of this question. I want to compile and execute new code at runtime in .NET. That being said...
I would like to allow the user to enter any equation, like the following, into a text box:
x = x / 2 * 0.07914
x = x^2 / 5
And have that equation applied to incoming data points. The incoming data points are represented by x and each data point is processed by the user-specified equation. I did this years ago, but I didn't like the solution because it required parsing the text of the equation for every calculation:
float ApplyEquation (string equation, float dataPoint)
{
// parse the equation string and figure out how to do the math
// lots of messy code here...
}
When you're processing boatloads of data points, this introduces quite a bit of overhead. I would like to be able to translate the equation into a function, on the fly, so that it only has to be parsed once. It would look something like this:
FunctionPointer foo = ConvertEquationToCode(equation);
....
x = foo(x); // I could then apply the equation to my incoming data like this
Function ConvertEquationToCode would parse the equation and return a pointer to a function that applies the appropriate math.
The app would basically be writing new code at run time. Is this possible with .NET?
Yes! Using methods found in the Microsoft.CSharp, System.CodeDom.Compiler, and System.Reflection name spaces. Here is a simple console app that compiles a class ("SomeClass") with one method ("Add42") and then allows you to invoke that method. This is a bare-bones example that I formatted down to prevent scroll bars from appearing in the code display. It is just to demonstrate compiling and using new code at run time.
using Microsoft.CSharp;
using System;
using System.CodeDom.Compiler;
using System.Reflection;
namespace RuntimeCompilationTest {
class Program
{
static void Main(string[] args) {
string sourceCode = #"
public class SomeClass {
public int Add42 (int parameter) {
return parameter += 42;
}
}";
var compParms = new CompilerParameters{
GenerateExecutable = false,
GenerateInMemory = true
};
var csProvider = new CSharpCodeProvider();
CompilerResults compilerResults =
csProvider.CompileAssemblyFromSource(compParms, sourceCode);
object typeInstance =
compilerResults.CompiledAssembly.CreateInstance("SomeClass");
MethodInfo mi = typeInstance.GetType().GetMethod("Add42");
int methodOutput =
(int)mi.Invoke(typeInstance, new object[] { 1 });
Console.WriteLine(methodOutput);
Console.ReadLine();
}
}
}
You might try this: Calculator.Net
It will evaluate a math expression.
From the posting it will support the following:
MathEvaluator eval = new MathEvaluator();
//basic math
double result = eval.Evaluate("(2 + 1) * (1 + 2)");
//calling a function
result = eval.Evaluate("sqrt(4)");
//evaluate trigonometric
result = eval.Evaluate("cos(pi * 45 / 180.0)");
//convert inches to feet
result = eval.Evaluate("12 [in->ft]");
//use variable
result = eval.Evaluate("answer * 10");
//add variable
eval.Variables.Add("x", 10);
result = eval.Evaluate("x * 10");
Download Page
And is distributed under the BSD license.
Yes, definitely possible to have the user type C# into a text box, then compile that code and run it from within your app. We do that at my work to allow for custom business logic.
Here is an article (I haven't more than skimmed it) which should get you started:
http://www.c-sharpcorner.com/UploadFile/ChrisBlake/RunTimeCompiler12052005045037AM/RunTimeCompiler.aspx
You can also create a System.Xml.XPath.XPathNavigator from an empty, "dummy" XML stream,
and evaluate expressions using the XPath evaluator:
static object Evaluate ( string xp )
{
return _nav.Evaluate ( xp );
}
static readonly System.Xml.XPath.XPathNavigator _nav
= new System.Xml.XPath.XPathDocument (
new StringReader ( "<r/>" ) ).CreateNavigator ( );
If you want to register variables to use within this expression,
you can dynamically build XML that you can pass in the Evaluate overload
that takes a XPathNodeIterator.
<context>
<x>2.151</x>
<y>231.2</y>
</context>
You can then write expressions like "x / 2 * 0.07914" and then x
is the value of the node in your XML context.
Another good thing is, you will have access to all XPath core functions,
which includes mathematics and string manipulation methods, and more stuff.
If you want to take it further, you can even build your own XsltCustomContext(or ill post here on demand)
where you can resolve references to extension functions and variables:
object result = Evaluate ( "my:func(234) * $myvar" );
my:func is mapped to a C#/.NET method which takes a double or int as parameter.
myvar is registered as a variable within the XSLT context.
You can try looking at either CodeDom or Lambda Expression Trees. I think either one of those should allow you to accomplish this. Expression trees are probably the better way to go but also have a higher learning curve.
I've done this using CSharpCodeProvider by creating the boiler plate class and function stuff as a const string inside my generator class. Then I insert the user code into the boiler plate and compile.
It was fairly straightforward to do, but the danger to this approach is that the user entering the equation could enter just about anything which could be a security issue depending on your application.
If security is at all a concern, I would recommend using Lambda Expression Trees, but if not, using CSharpCodeProvider is a fairly robust option.
Have you seen http://ncalc.codeplex.com ?
It's extensible, fast (e.g. has its own cache) enables you to provide custom functions and varaibles at run time by handling EvaluateFunction/EvaluateParameter events. Example expressions it can parse:
Expression e = new Expression("Round(Pow(Pi, 2) + Pow([Pi2], 2) + X, 2)");
e.Parameters["Pi2"] = new Expression("Pi * Pi");
e.Parameters["X"] = 10;
e.EvaluateParameter += delegate(string name, ParameterArgs args)
{
if (name == "Pi")
args.Result = 3.14;
};
Debug.Assert(117.07 == e.Evaluate());
It also handles unicode & many data type natively. It comes with an antler file if you want to change the grammer. There is also a fork which supports MEF to load new functions.
You could start here and if you really want to get into it, Boo can be modified to meet your needs. You could also integrate LUA with .NET. Any three of these could be utilized within the body of a delegate for your ConvertEquationToCode.
Try Vici.Parser: download it here (free) , it's the most flexible expression parser/evaluator I've found so far.
Here a more modern library for simple expressions: System.Linq.Dynamic.Core.
It's compatible with .NET Standard/.NET Core, it's available through NuGet, and the source is available.
https://system-linq-dynamic-core.azurewebsites.net/html/de47654c-7ae4-9302-3061-ea6307706cb8.htm
https://github.com/StefH/System.Linq.Dynamic.Core
https://www.nuget.org/packages/System.Linq.Dynamic.Core/
This is a very lightweight and dynamic library.
I wrote a simple wrapper class for this library that let's me do things like this:
string sExpression = "(a == 0) ? 5 : 10";
ExpressionEvaluator<int> exec = new ExpressionEvaluator<int>(sExpression);
exec.AddParameter("a", 0);
int n0 = exec.Invoke();
Once the expression is compiled, you can simply update the parameter values and re-invoke the expression.
If all else fails, there are classes under the System.Reflection.Emit namespace which you can use to produce new assemblies, classes, and methods.
You could implement a postfix stack calculator. Basically what you have to do is convert the expression to postfix notation, and then simply iterate over the tokens in your postfix to calculate.
I would do a recursive function that doesn't write code but instead applies basic operators to portions of a string based on special characters found in that string.
If more than one special character is found, it breaks up the string and calls itself on those two portions.
you can use system.CodeDom to generate code and compile it on the fly
have a look here
I don't know if it's possible to implement your ConvertEquationToCode function, however, you can generate a data structure that represents the calculation you need to perform.
For example, you could build a tree whose leaf nodes represent the input for your calculation, whose non-leaf nodes represent intermediate results, and whose root node represents the whole calculation.
It has some advantages. For example, if you're doing what-if analysis and want to change the value of one input at a time, you can recalculate the results that depend on the value that you have changed, while retaining the results that don't.