views:

11264

answers:

11
+15  Q: 

C# eval equivalent?

I can do an eval("something()"); to execute the code dynamically in JavaScript. Is there a way for me to do the same thing in C#?

What I am exactly trying to do is that I have an integer variable (say i) and I have multiple properties by the names: "Property1","Property2","Property3" etc. Now, I want to perform some operations on the " Propertyi " property depending on the value of i.

This is really simple with Javascript. Is there any way to do this with C#?

Edit: Oh, and I am using C# 2.0

+2  A: 

You can use reflection to get the property and invoke it. Something like this:

object result = theObject.GetType().GetProperty("Property" + i).GetValue(theObject, null);

That is, assuming the object that has the property is called "theObject" :)

Ch00k
A: 

You could do it with a prototype function:

void something(int i, string P1) {
    something(i, P1, String.Empty);
}

void something(int i, string P1, string P2) {
    something(i, P1, P2, String.Empty);
}

void something(int i, string P1, string P2, string P3) {
    something(i, P1, P2, P3, String.Empty);
}

and so on...

GateKiller
+12  A: 

Not really. You can use reflection to achieve what you want, but it won't be nearly as simple as in Javascript. For example, if you wanted to set the private field of an object to something, you could use this function:

  protected static void SetField(object o, string fieldName, object value)
{
FieldInfo field = o.GetType().GetField(fieldName, BindingFlags.Instance | BindingFlags.NonPublic);
field.SetValue(o, value);
}
Karl Seguin
+14  A: 

Unfortunately, C# isn't a dynamic language like that.

What you can do, however, is to create a C# source code file, full with class and everything, and run it through the CodeDom provider for C# and compile it into an assembly, and then execute it.

This forum post on MSDN contains an answer with some example code down the page somewhat: http://forums.msdn.microsoft.com/en-US/csharpgeneral/thread/6a783cc4-bb54-4fec-b504-f9b1ed786b54/

I would hardly say this is a very good solution, but it is possible anyway.

What kind of code are you going to expect in that string? If it is a minor subset of valid code, for instance just math expressions, it might be that other alternatives exists.


Edit: Well, that teaches me to read the questions thoroughly first. Yes, reflection would be able to give you some help here.

If you split the string by the ; first, to get individual properties, you can use the following code to get a PropertyInfo object for a particular property for a class, and then use that object to manipulate a particular object.

String propName = "Text";
PropertyInfo pi = someObject.GetType().GetProperty(propName);
pi.SetValue(someObject, "New Value", new Object[0]);

Link: http://msdn.microsoft.com/en-us/library/system.reflection.propertyinfo.setvalue(VS.71).aspx

Lasse V. Karlsen
+5  A: 

All of that would definitely work. Personally, for that particular problem, I would probably take a little different approach. Maybe something like this:

class MyClass {
public Point point1, point2, point3;

private Point[] points;

public MyClass() {
//...
this.points = new Point[] {point1, point2, point3};
}

public void DoSomethingWith(int i) {
Point target = this.points[i+1];
// do stuff to target
}
}

When using patterns like this, you have to be careful that your data is stored by reference and not by value. In other words, don't do this with primitives. You have to use their big bloated class counterparts.

I realized that's not exactly the question, but the question has been pretty well answered and I thought maybe an alternative approach might help.

MojoFilter
A: 

Do the the properties have to be properties? Why not use a list to group the properties and reference them by index?

Graham Miller
+1  A: 

Don't use reflection, it's dirty (I really don't like it).

Wait for .NET 4.0 and use Expression Trees: http://community.bartdesmet.net/blogs/bart/archive/2009/08/10/expression-trees-take-two-introducing-system-linq-expressions-v4-0.aspx

Snake
"dirty"? Data binding and serialisation are built on top of reflection, so it can't be that bad. :-)
Christian Hayter
I know, it's very powerful. And with great power comes great responsibility. And a user who asks this type of question shouldn't touch reflection.
Snake
+1  A: 

I don't now if you absolutely want to execute C# statements, but you can already execute Javascript statements in C# 2.0. The open-source library Jint is able to do it. It's a Javascript interpreter for .NET. Pass a Javascript program and it will run inside your application. You can even pass C# object as arguments and do automation on it.

Also if you just want to evaluate expression on your properties, give a try to NCalc.

Sébastien Ros
+2  A: 

My C# Eval program allows you to do this. It accepts a substantial subset of the C# language and compiles it at run time into dynamic methods. Look at my website KamimuCode.Com for the full details.

David Wynne
A: 

This is a very simple approach that is easy to understand. Just use another variable to reference the one you want.

string Property1 = "data 1";
string Property2 = "data 2";
string Property3 = "data 3";

int i = 2;
string whichProperty = "";

if (i == 1) { whichProperty = Property1; }
if (i == 2) { whichProperty = Property2; }
if (i == 3) { whichProperty = Property3; }

//now use the member variable that was set
int mathResult = getScores(whichProperty);

Otherwise you should learn to use ILists or arrays, or anything else to hold a series of values or settings.

A: 

You also could implement a Webbrowser, then load a html-file wich contains javascript.

Then u go for the document.InvokeScript Method on this browser. The return Valua of the eval function can be catched and converted into everything you need.

I did this in several Projects and it works perfectly.

Hope ist helps

Xodem