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#?
An example of what I am trying to do is: 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#?
Using the Roslyn scripting API (more samples here):
// add NuGet package 'Microsoft.CodeAnalysis.Scripting'
using Microsoft.CodeAnalysis.CSharp.Scripting;
await CSharpScript.EvaluateAsync("System.Math.Pow(2, 4)") // returns 16
You can also run any piece of code:
var script = await CSharpScript.RunAsync(#"
class MyClass
{
public void Print() => System.Console.WriteLine(1);
}")
And reference the code that was generated in previous runs:
await script.ContinueWithAsync("new MyClass().Print();");
DISCLAIMER: This answer was written back in 2008. The landscape has changed drastically since then.
Look at the other answers on this page, especially the one detailing Microsoft.CodeAnalysis.CSharp.Scripting.
Rest of answer will be left as it was originally posted but is no longer accurate.
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:
create a anonymous method from a string?
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: PropertyInfo.SetValue Method
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);
}
This is an eval function under c#. I used it to convert anonymous functions (Lambda Expressions) from a string.
Source: http://www.codeproject.com/KB/cs/evalcscode.aspx
public static object Eval(string sCSCode) {
CSharpCodeProvider c = new CSharpCodeProvider();
ICodeCompiler icc = c.CreateCompiler();
CompilerParameters cp = new CompilerParameters();
cp.ReferencedAssemblies.Add("system.dll");
cp.ReferencedAssemblies.Add("system.xml.dll");
cp.ReferencedAssemblies.Add("system.data.dll");
cp.ReferencedAssemblies.Add("system.windows.forms.dll");
cp.ReferencedAssemblies.Add("system.drawing.dll");
cp.CompilerOptions = "/t:library";
cp.GenerateInMemory = true;
StringBuilder sb = new StringBuilder("");
sb.Append("using System;\n" );
sb.Append("using System.Xml;\n");
sb.Append("using System.Data;\n");
sb.Append("using System.Data.SqlClient;\n");
sb.Append("using System.Windows.Forms;\n");
sb.Append("using System.Drawing;\n");
sb.Append("namespace CSCodeEvaler{ \n");
sb.Append("public class CSCodeEvaler{ \n");
sb.Append("public object EvalCode(){\n");
sb.Append("return "+sCSCode+"; \n");
sb.Append("} \n");
sb.Append("} \n");
sb.Append("}\n");
CompilerResults cr = icc.CompileAssemblyFromSource(cp, sb.ToString());
if( cr.Errors.Count > 0 ){
MessageBox.Show("ERROR: " + cr.Errors[0].ErrorText,
"Error evaluating cs code", MessageBoxButtons.OK,
MessageBoxIcon.Error );
return null;
}
System.Reflection.Assembly a = cr.CompiledAssembly;
object o = a.CreateInstance("CSCodeEvaler.CSCodeEvaler");
Type t = o.GetType();
MethodInfo mi = t.GetMethod("EvalCode");
object s = mi.Invoke(o, null);
return s;
}
I have written an open source project, Dynamic Expresso, that can convert text expression written using a C# syntax into delegates (or expression tree). Expressions are parsed and transformed into Expression Trees without using compilation or reflection.
You can write something like:
var interpreter = new Interpreter();
var result = interpreter.Eval("8 / 2 + 2");
or
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);
My work is based on Scott Gu article http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx .
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.
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.
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" :)
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 Value of the eval function can be catched and converted into everything you need.
I did this in several Projects and it works perfectly.
Hope it helps
Uses reflection to parse and evaluate a data-binding expression against an object at run time.
DataBinder.Eval Method
I have written a package, SharpByte.Dynamic, to simplify the task of compiling and executing code dynamically. The code can be invoked on any context object using extension methods as detailed further here.
For example,
someObject.Evaluate<int>("6 / {{{0}}}", 3))
returns 3;
someObject.Evaluate("this.ToString()"))
returns the context object's string representation;
someObject.Execute(#
"Console.WriteLine(""Hello, world!"");
Console.WriteLine(""This demonstrates running a simple script"");
");
runs those statements as a script, etc.
Executables can be gotten easily using a factory method, as seen in the example here--all you need is the source code and list of any expected named parameters (tokens are embedded using triple-bracket notation, such as {{{0}}}, to avoid collisions with string.Format() as well as Handlebars-like syntaxes):
IExecutable executable = ExecutableFactory.Default.GetExecutable(executableType, sourceCode, parameterNames, addedNamespaces);
Each executable object (script or expression) is thread-safe, can be stored and reused, supports logging from within a script, stores timing information and last exception if encountered, etc. There is also a Copy() method compiled on each to allow creating cheap copies, i.e. using an executable object compiled from a script or expression as a template for creating others.
Overhead of executing an already-compiled script or statement is relatively low, at well under a microsecond on modest hardware, and already-compiled scripts and expressions are cached for reuse.
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...
I was trying to get a value of a structure (class) member by it's name. The structure was not dynamic. All answers didn't work until I finally got it:
public static object GetPropertyValue(object instance, string memberName)
{
return instance.GetType().GetField(memberName).GetValue(instance);
}
This method will return the value of the member by it's name. It works on regular structure (class).
You might check the Heleonix.Reflection library. It provides methods to get/set/invoke members dynamically, including nested members, or if a member is clearly defined, you can create a getter/setter (lambda compiled into a delegate) which is faster than reflection:
var success = Reflector.Set(instance, null, $"Property{i}", value);
Or if number of properties is not endless, you can generate setters and chache them (setters are faster since they are compiled delegates):
var setter = Reflector.CreateSetter<object, object>($"Property{i}", typeof(type which contains "Property"+i));
setter(instance, value);
Setters can be of type Action<object, object> but instances can be different at runtime, so you can create lists of setters.
Unfortunately, C# doesn't have any native facilities for doing exactly what you are asking.
However, my C# eval program does allow for evaluating C# code. It provides for evaluating C# code at runtime and supports many C# statements. In fact, this code is usable within any .NET project, however, it is limited to using C# syntax. Have a look at my website, http://csharp-eval.com, for additional details.
the correct answer is you need to cache all the result to keep the mem0ry usage low.
an example would look like this
TypeOf(Evaluate)
{
"1+1":2;
"1+2":3;
"1+3":5;
....
"2-5":-3;
"0+0":1
}
and add it to a List
List<string> results = new List<string>();
for() results.Add(result);
save the id and use it in the code
hope this helps
I want to save the list of type Myclass in PlayerPrefs.
I saw an example with converting in a String, how can I do that?
public class MyClass{
private int ex;
}
List<MyClass> l = new List<MyClass>();
//How to save it?
Approach using JSON to serialize/deserialize your object into string is the better option in my personal opinion.
You can find a lot of JSON libs for C#, just research for it and find one that suits better for you.
Or take a look at unity wiki ArrayPrefs2 and extends or use it to create your own parser to save your object structures. I, personally, wouldn't recommend this approach to save entire objects but is an option to mention...
When your object is simple enough to use JsonConverter from Newtonsoft as suggested by Povl Eller:
To Save
Character char = new Character();
char.Name = "Apple";
char.Level = 1;
char.Health = 150;
char.Attributes = new int[] { 10, 10, 10 };
PlayerPrefs.SetString( "PlayerCharacter", JsonConvert.SerializeObject(char) );
To Load
Character char = JsonConvert.DeserializeObject<Character>( PlayerPrefs.GetString( "PlayerCharacter" ) );
If you need to control the serialization for more complex objects or something you can use JsonSerializer that is documented in this same link at newtonsoft website.
OBS: I write this code directly here and didn't test it, probably you'll need to adjust it to be useful...
Perhaps something like
for(int i=0;i<list.length;i++)
{
PlayerPrefs.SetString(list(i).name, list(i).value);
}
Try to use newtonsoft.json.
They have extended examples and these two should get you started:
http://www.newtonsoft.com/json/help/html/SerializeObject.htm
http://www.newtonsoft.com/json/help/html/DeserializeObject.htm
Best Regards
Is there a way to make ServiceStack.Redis use JSON.NET instead of ServiceStack.Text?
The reason I am asking is because of a specific case where integers are converted to strings in ServiceStack.Text but not in JSON.NET
This is a huge deal when sending data over the wire to the web.
In our specific case, JSON.NET stores data as
'Offset': 0
and ServiceStack.Text stores data as
'Offset' : '0'
Why is this very bad? In javascript, 29 + 0 = 29 but 29 + '0' = '290'. This means array[29 + offset] can yield strange results with ServiceStack.Text
I know this is a specific use case, but it'll be a lot easier to use JSON.NET (which behaves as expected) instead of ServiceStack.Text (which is 3 times faster but does not behave as expected).
It does not store numbers as text, Actual behavior in ServiceStack.Text:
public class HasOffset
{
public int Offset { get; set; }
}
var dto = new HasOffset { Offset = 1 };
string json = dto.ToJson();
json.Print(); //prints {"Offset":1}
var fromJson = json.FromJson<HasOffset>();
Assert.That(fromJson.Offset, Is.EqualTo(1));
If you're trying to deserialize it using JsonObject it gets parsed into a Dictionary<string,string> Dictionary it gets coerced to a string. Likewise if you're trying to store it into a object the serializer doesn't know what type it should convert it to so it leaves it as a string.
At the moment you can only switch between ServiceStack's JsonSerializer and the built-in JsonDataContractSerializer which you can do by adding this to the AppHost.Configure section:
SetConfig(new EndpointHostConfig {
UseBclJsonSerializers = true
});
Please see this thread for the reference to the above information.
It would appear that they simply don't support an out-of-box configurable option for different serializers.
I am trying to serialize an array of my dataobjects through WCF with protobuf-net.
If I serialize the Array of my dataobjects manually, it works successfully:
var proto = Serializer.CreateFormatter<DataType[]>();
which is way faster and smaller than the ordinary binary xml DataContractSerializer - thats why I wanna use it!
The 'DataType' class is just an example - I have many of those. When the reponse of my service is just a single object, everything works just fine.
But when my service returns an Array of objects it seems it does not know what to do and uses the ordinary DataContractSerializer.
The ProtoBehavior is applied:
endpoint.Behaviors.Add(new ProtoBuf.ServiceModel.ProtoEndpointBehavior());
My dataobject is more or less like that:
[Serializable]
[DataContract]
[ProtoContract]
public class DataType
{
[DataMember(EmitDefaultValue = false, Name = "K")]
[ProtoMember(1)]
public string Key { get; set; }
// many more to come
}
and that's basically my service:
[ServiceContract(CallbackContract = typeof(IBaseDataObjectUpdate), SessionMode = SessionMode.Required)]
[ServiceKnownType("GetKnownTypes", typeof(KnownTypesProvider))]
public interface IDataTypeService
{
[OperationContract]
DataType[] Load(Filter[] filter, Guid clientGuid);
// some more
}
I could track it down to the TryCreate in the XmlProtoSerializer. The call:
int key = GetKey(model, ref type, out isList);
does not return a valid key, therefore no XmlProtoSerializer is created.
That explains the behavior, but what are my options here?
I found an old answer of Marc Gravell where he suggests the creation of an object which consists of the Array. But as it is from 2011 it might be outdated:
https://stackoverflow.com/a/6270267/2243584
Or can I add the model to protobuf-net somehow manually? As mentioned above the manual serialization is working.
Any comment is appreciated!
OK, so far I have come up with 2 solutions.
Do not use Arrays! It works with any other collection. Which caused me to investigate and leaded to solution:
Support Arrays in protobuf-net
I have adapted the method internal static Type GetListItemType(TypeModel model, Type listType) in the TypeMode class as follows:
if (listType.IsArray) // NEW
{
if (listType.GetElementType() == typeof(byte))
return null;
}
if (listType == model.MapType(typeof(string)) // || listType.IsArray // CHANGED!!!
|| !model.MapType(typeof(IEnumerable)).IsAssignableFrom(listType)) return null;
I think I did figure out why arrays are excluded. Because if you support byte[], you get some problems when finally sending the data to the wire. At least I got some Assert and exception in the encode factory when dealing with byte[].
As I have no idea on the side effects of solution Nr. 2 - I stick with solution Nr. 1.
Nevertheless I am quite keen on a comment from Marc - of course, everybody is welcome!
Is it possible to know the length of a string array - without having an object instance - via reflection?
E.g. in this case: 2.
public string[] Key
{
get { return new string[] { Name, Type }; }
}
EDIT: ok, I will not try to do this, it doesn't make much sense.
Perhaps you mean "without having the exact type of the Array". C# Arrays all derive from Array, so you can cast an Array reference to Array and use the Length property.
If you TRULY wants to reflect the property,
var type = typeof(MyClass);
var prop = type.GetProperty("Key");
var method = prop.GetGetMethod();
var body = method.GetMethodBody();
var ils = body.GetILAsByteArray();
from here you'll have to use one of the various libraries to decode bytes to IL OpCodes (for example https://gist.github.com/104001) . The OpCode you are looking for is newarr. The last push of an int32 before the newarr is the size of the array.
You have two things going on there... telling the length of an array is pretty simple once you have an array; you just call .Length (in the case of a vector).
However, you mention an instance, and you are showing an instance property; which makes me think it is the containing object you lack. In which case... no. You can't make a virtcall on a null instance. And trying to use static-call on an instance member of a class is very evil; IIRC the runtime will kick you for this.
You could, however, make it a static property just by adding the static modifier. Then you just pass in null as the instance to reflection.
I guess you mean you want to know the size of the array the property will return if it were called?
I don't think you can do it sensibly.
If the property had a conditional then it could return different sized arrays, so
you'd have to evaluate the property to know the size. Which could have side effects or be dependent on other values in the object (or statics).
Consider this one:-
static public int n;
public string[] Key
{
get {
if (n > 1)
return new string[] { "Name", "Type" };
else
return new string[] { "Name", "Type", "Cheese" };
}
}
Basically, you'd have to run the code.