from expression to string literal - how ?

  • Thread starter Thread starter Bob M
  • Start date Start date
B

Bob M

If I define an expression or equation, how can I retrieve that expression as
string literal? I want to do this so that I could avoid repetitive typing
(or copy/paste/change) the same thing at two place. I try to demonstrate
the problem in the following code.

Bob M


<%@ Page Language="C#" %>
<script runat="server">

public static double givenFn(double x) {

return (Math.Pow(x, 3) + (3 * Math.Pow(x, 2)) - (10 * x));
}

protected void Page_Load(object sender, EventArgs e) {

Label1.Text = "The given function is: " + "Math.Pow(x, 3) + (3 *
Math.Pow(x, 2)) - (10 * x)";
}


</script>

<html>
<body>
<form id="form1" runat="server">
<div>
<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
</div>
</form>
</body>
</html>
 
Bob,

If the "Math.Pow(x, 3) + (3 * Math.Pow(x, 2)) - (10 * x)" is constant,
then you can use the const keyword to specify it in one place:

// At the class level:
private const string FunctionExpression = "Math.Pow(x, 3) + (3 * Math.Pow(x,
2)) - (10 * x)";

If it makes sense only to have the constant in the scope of the current
method/property, then you can do this:

// In a method:
const string FunctionExpression = "Math.Pow(x, 3) + (3 * Math.Pow(x, 2)) -
(10 * x)";

If your expression can be generated depending on different parameters,
then create a method which will generate the expression for you, and use
that.
 
Hi Nicholas,

Thanks. But I have to use that function (x^3 + 3x^2 - 10x) later in my
application code. If I specify
"Math.Pow(x, 3) + (3 * Math.Pow(x, > 2)) - (10 * x)" as string constant at
one place, then how can I use this string constant in the return statement
in the givenFn()method?

My problem is a little bit different. Perhaps my code example did not
elaborate the problem I am trying to convey. The revised code is posted
again:

<%@ Page Language="C#" %>
<script runat="server">

public static double givenFn(double x) {

return (Math.Pow(x, 3) + (3 * Math.Pow(x, 2)) - (10 * x)); // function
expression
}

protected void Page_Load(object sender, EventArgs e) {

Label1.Text = "f(x)=" + "Math.Pow(x, 3) + (3 * Math.Pow(x, 2)) - (10 *
x)";
// Can this second string literal
be retrieved
// from the function expression in
// givenFn() method to avoid typing
(copy/paste

Label2.Text = "f(x) = " + givenFn(6) + " at x=6";
}

</script>
<html><body><form id="form1" runat="server">
<div>
<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
<br />
<asp:Label ID="Label2" runat="server" Text="Label"></asp:Label>
</div>
</form></body></html>
 
For your convenience I post example code as Console Application:
using System;

class ProgramConsole {

private const string StrGivenFn = "Math.Pow(x, 3) + (3 * Math.Pow(x, 2)) -
(10 * x)";

public static double givenFn(double x) {

return (Math.Pow(x, 3) + (3 * Math.Pow(x, 2)) - (10 * x));

// The expression following return statement is

// same as the constant StrGivenFn. How can StrGivenFn be used?

}

static void Main(string[] args) {

Console.WriteLine("f(x) = " + StrGivenFn);

Console.WriteLine("f(x) = " + givenFn(6) + " at x=6");

Console.ReadLine();

}

}
 
* Bob M wrote, On 21-5-2007 22:27:
For your convenience I post example code as Console Application:
using System;

class ProgramConsole {

private const string StrGivenFn = "Math.Pow(x, 3) + (3 * Math.Pow(x, 2)) -
(10 * x)";

public static double givenFn(double x) {

return (Math.Pow(x, 3) + (3 * Math.Pow(x, 2)) - (10 * x));

// The expression following return statement is

// same as the constant StrGivenFn. How can StrGivenFn be used?

}

static void Main(string[] args) {

Console.WriteLine("f(x) = " + StrGivenFn);

Console.WriteLine("f(x) = " + givenFn(6) + " at x=6");

Console.ReadLine();

}

}

The answer is as you've feared all along, you cannot. At least not
without writing a full blown parser or finding a component that can
interpret your function. It's not in the base class library. Sorry.

Jesse
 
Hi Jesse,

I am sorry to hear that "a string literal can not be converted to a C#
expression" (or vice versa).

But I have seen some websites where users can enter a mathematical
expression in a TextBox and gets some result after submitting. I do not
know how they do it. Maybe they use what you mention: full blown parser or
some component.

Bob_M
 
Bob said:
For your convenience I post example code as Console Application:
using System;

class ProgramConsole {

private const string StrGivenFn = "Math.Pow(x, 3) + (3 * Math.Pow(x, 2)) -
(10 * x)";

public static double givenFn(double x) {

return (Math.Pow(x, 3) + (3 * Math.Pow(x, 2)) - (10 * x));

// The expression following return statement is

// same as the constant StrGivenFn. How can StrGivenFn be used?

}

static void Main(string[] args) {

Console.WriteLine("f(x) = " + StrGivenFn);

Console.WriteLine("f(x) = " + givenFn(6) + " at x=6");

Console.ReadLine();

}

}

You want to evaluate a C# expression at runtime ?

You can call the compiler.

Below are some code to get you started.

Arne

==============================================================

using System;
using System.Collections.Generic;
using System.Reflection;
using System.CodeDom.Compiler;

using Microsoft.CSharp;

namespace E
{
public class DynComp
{
private static int n = 0;
private static Dictionary<string,object> m = new
Dictionary<string,object>();
public static double Eval(string expr, double x)
{
object o;
if(m.ContainsKey(expr))
{
o = m[expr];
}
else
{
n++;
string cn = "c" + n;
string src = "using System; public class " + cn + " { public static
double Eval(double x) { return " + expr + "; } }";
CodeDomProvider comp = new CSharpCodeProvider();
CompilerParameters param = new CompilerParameters();
param.GenerateInMemory = true;
param.ReferencedAssemblies.Add("System.dll");
CompilerResults res = comp.CompileAssemblyFromSource(param,
src);
Assembly asm = res.CompiledAssembly;
o = asm.CreateInstance(cn);
m.Add(expr, o);
}
return (double)o.GetType().InvokeMember("Eval",
BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Static |
BindingFlags.InvokeMethod, null, null, new object[] { x });
}
}
public class MainClass
{
private const string StrGivenFn = "Math.Pow(x, 3) + (3 * Math.Pow(x,
2)) - (10 * x)";
public static double GivenFn(double x) {
return (Math.Pow(x, 3) + (3 * Math.Pow(x, 2)) - (10 * x));
}
public static void Main(string[] args)
{
Console.WriteLine(GivenFn(6));
Console.WriteLine(DynComp.Eval("Math.Pow(x, 3) + (3 * Math.Pow(x, 2))
- (10 * x)", 6));
Console.ReadLine();
}
}
}
 
Arne said:
You want to evaluate a C# expression at runtime ?

You can call the compiler.

Below are some code to get you started.

I'm not sure I'd want to put that on my webpage!
Talk about a security hole! :-)

Alun Harford
 
My though exactly... after all,
@"System.Diagnostics.Process.Start(""random.exe"").Id" is well-formed,
uses only "System" and returns a number ;-p
Even with partial trust I wouldn't want this *near* production code...
unless I really, really trust the input.

But if anyone has a parser...? I'm actually faced with a very similar
problem at the moment; I want to implement a filtered IBindingListView
(from scratch). This is very easy if I use a Predicate<T> - but if I
want to support the Filter property? Much harder... DataView uses
ExpressionParser, but this is internal and DataTable specific... does
anybody know of a viable implementation?

I'm thinking I'll live with a Predicate<T> for now ;-p It meets all my
needs... but it would be quite satisfying to finish the implementation
(since every other IBindingList / IBindingListView contract is met...)

Marc
 
Alun said:
I'm not sure I'd want to put that on my webpage!
Talk about a security hole! :-)

Good point.

But it is unavoidable if the requirement is to evaluate C#.

Requirements need to change.

Arne
 
Back
Top