How to dynamically set variable value with C#? - c#

For example, PHP code:
$test = "hello";
${$test} = $test;
echo $hello; // return hello
How to do this in C#? Thanks in advance.
UPD: Dynamic variable in C#? - here is an answer.

This isn't supported in C#. You could use an ExpandoObject and set a member on it, but it's not quite the same as the PHP code. You'll still need to refer to the ExpandoObject by a variable name.
dynamic myObject = new ExpandoObject();
string test = "Hello";
((IDictionary<string, object>)myObject).Add(test, test);
Console.WriteLine(myObject.Hello);
Nonetheless, this doesn't help with code clarity. If all you want to do is map a name to a value you can use a Dictionary, which is really what ExpandoObject uses internally, as demonstrated by the cast in the code above.

C# is not designed for that sort of thing at the language level. You will have to use reflection to achieve that, and only for fields, not local variables (which cannot be accessed via reflection).

Such dynamic access to class members can be achieved via reflection.
class Foo
{
string test;
string hello;
void Bar()
{
test = "hello";
typeof(Foo).InvokeMember( test,
BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.SetField,
null, this, new object[] { "newvalue" } );
}
}

Related

Can I get PropertyInfo for a field or property in a class without using reflection?

I have tried searching around using Expressions but not able to find something by which I can access the fields or properties of a class without using reflection.
Basically, I will get a string at runtime, and I know that that string will be a property of the class, but I need to validate that it indeed is a property inside that class.
e.g. If I have a class:
class Test { string a; public string b {get;set;} }
I get the string values a and b at runtime and I need to verify that they exist inside the class Test
What I know till now from researching is that I can do:
string one = "a";
string two = "b";
PropertyInfo result1 = typeof(Test).GetProperty(one);
PropertyInfo result2 = typeof(Test).GetProperty(two);
But this code is using reflection. I want to know if there is some way I can do this without using reflection?
Can I do this using Expressions?
With an expression, you can get the a PropertyInfo the following way:
Test t = new Test();
t.b = "sadf";
Expression<Func<string>> exp = () => t.b;
var memExp = exp.Body as MemberExpression;
MemberInfo member = memExp.Member;
PropertyInfo property = (PropertyInfo)member;
Console.WriteLine(property.GetValue(t));
This will output the value of your property of your variable (sadf in the example). But what do you want to achieve? Why don't you collect the PropertyInfo from the Type? Because it is quite possible that under the hood, this code will use reflection the very same way you did (the same as LINQ still uses loop, but the programer just doesn't see it).

Direct memory access to underlying field data

I'm looking for a way to avoid FieldInfo.Get/SetValue overhead, and access memory directly for a few select, known ahead of time, primitive types. (Most specifically, I'm looking to avoid any memory allocations in our custom serializer)
Basically, here's what the official way allows me to do:
System.Object o = someobject;
int inOut = 0;
var type = o.GetType();
var fieldInfos = type.GetFields(BindingFlags.Public | BindingFlags.Instance);
foreach (var fi in fieldInfos) {
fi.SetValue(o, inOut);
inOut = (int)fi.GetValue(o);
}
And here's roughly what I'd like to do:
foreach (var fi in fieldInfos) {
fixed(int* ip = o.basePointer + fi.fieldOffset) {
*p = inOut;
inOut = *p;
}
}
I would use this only for Int32, Single, and possibly bools. I'm primarily interested in getting this working on Mono, so if there's anything Mono specific available, that'd be fine.
Note: I'm well aware of the "you shouldn't be doing this", and "have you profiled it" etc. I know, and I have, which is why I'm looking into this. We have a very specific case, where we control all variables (and all code), but we would like it to work on any 'normal' class without requiring additional markup or explicit struct layout.
EDIT: I should point out that I'm not able to emit dynamic code to solve this. I'm ok with a solution requiring me to write and assemble IL up-front though.
I'm well aware of the "you shouldn't be doing this"
That is good - I'll skip this part of the explanation then, and go straight to a way of accessing fields that avoids memory allocation, while staying within the limits of managed code.
You can use LINQ expressions to construct a Func<ObjType,int> for a getter and Action<ObjType,int> for a setter. Calling these functors would let you get or set int fields as if you were accessing their methods directly.
Here is how you can make a wrapper-free getter:
public class Test
{
public int myfield;
public static void Main()
{
// Make a parameter expression to represent the object
var argExpr = Expression.Parameter(typeof(Test), "a");
// Get the field of your object (the same way as in your first example)
var field = typeof(Test).GetField("myfield", BindingFlags.Public | BindingFlags.Instance);
// Make an expression accessing the field from the parameter
var fieldExpr = Expression.Field(argExpr, field);
// Compile the expression into a functor
var getter = (Func<Test,int>)Expression.Lambda(fieldExpr, argExpr).Compile();
// Construct a test object
var tmp = new Test {myfield = 123};
// Use a wrapper to avoid "boxing"/"unboxing" of "GetValue"
int res = getter(tmp);
Console.WriteLine("Res={0}", res);
}
}
Demo on ideone.
Construct the setter in a similar way, using one more parameter of type int, and Expression.Assign. The resultant lambda will compile into an Action<Test,int> rather than Func<Test,int>, because setters do not return value.
You say, that you can't use dynamic code generation. Here are some other ideas:
If you can work with properties instead of fields, create a delegate to the property getter (https://stackoverflow.com/a/724427).
Generate IL code for your serializer at build time. Compile that into an assembly that you can load at runtime. Just generate accessor code for each and every field. I think you can access private members in IL when FullTrust and SkipVerification permissions are present.

how to cast this string list to an object

If I have this string list:
string myObjectString = "MyObject, SetWidth, int, 10, 0, 1";
in which:
- MyObject: the object class
- SetWidth: the property of the object
- int: type of the SetWidth is int
- 10: default value
- 0: object order
- 1: property order
Then how can I construct an object like this:
[ObjectOrder(0)]
public class MyObject:
{
private int _SetWidth = 10;
[PropertyOrder(1)]
public int SetWidth
{
set{_SetWidth=value;}
get{return _SetWidth;}
}
}
So, I would like have something like this:
Object myObject = ConstructAnObject(myObjectString);
and the myObject is an instance of MyObject. Could it be possible in C#?
Thanks in advance.
I think you better use the Object Serialization/Deserialization instead of creating a custom method that basically needs to do the same thing
more info at:
http://msdn.microsoft.com/en-us/library/ms233843.aspx
Here is some quick and dirty code to get you started:
string myObjectString = "MyObject, SetWidth, int, 10, 0, 1";
var info = myObjectString.Split(',');
string objectName = info[0].Trim();
string propertyName = info[1].Trim();
string defaultValue = info[3].Trim();
//find the type
Type objectType = Assembly.GetExecutingAssembly().GetTypes().Where(t=>t.Name.EndsWith(objectName)).Single();//might want to redirect to proper assembly
//create an instance
object theObject = Activator.CreateInstance(objectType);
//set the property
PropertyInfo pi = objectType.GetProperty(propertyName);
object valueToBeSet = Convert.ChangeType(defaultValue, pi.PropertyType);
pi.SetValue(theObject, valueToBeSet, null);
return theObject;
This will find the MyObject, create an object of the proper propertytype, and set the matching property.
If you use C# 4.0, you can use the new dynamic feature.
string myObjectString = "MyObject, SetWidth, int, 10, 0, 1";
String[] properties = myObjectString.Split(',');
dynamic myObj;
myObj.MyObject = (objtect)properties[0];
myObj.SetWidth = Int32.Parse(properties[1]);
// cast dynamic to your object. Exception may be thrown.
MyObject result = (MyObject)myObj;
I don't quite understand why do you need ObjectOrder and PropertyOrder... Once you have their names you probably don't need them, at least for "deserialization"...
Or please advice what is their role?
You definitely can simply do it via reflection:
Split the string by comma (using myString.Split)
Use reflection to find an object within your application:
Find the type with name = splittedString[0] (enumerate all the assemblies within the domain and all the types within each assembly);
Instantiate the type found (using Activator.CreateInstance)
Find the property by name (Using objectType.GetProperty)
Set the property value (using propertyInfo.SetValue)
Return the object
Assuming you need to generate new types there are two possible ways to do so:
Using Reflection Emit
Using CodeDom provider
I think the simpler solution is CodeDom provider. All needed is to generate the source as a string in memory, and then compile the code and instantiate a new instance with Activator. This is a nice example I just found.
The reason I think that CodeDom provider is simpler is that it has shorter setup - no need to generate dynamic module and assembly and then work with type builder and members builder. In addition, it doesn't require working with IL to generate the getter and setter bodies.
An advantage that reflection emit has is performance - dynamic module can add more types to itself even after one of the types was used. CodeDom provider requires creating all the types at once, otherwise it creates a new assembly each time.

Casting anonymous type to dynamic

I have a function that returns an anonymous type which I want to test in my MVC controller.
public JsonResult Foo()
{
var data = new
{
details = "something",
more = "More"
};
return Json(data);
}
I want to verify the data I get from the Foo function, What I'm doing now is getting the data type and get it's properties values with reflection.
[Test]
public void TestOne()
{
var data = _controller.Foo().Data;
var details = data.GetType().GetProperty("details").GetValue(data, null);
var more = data.GetType().GetProperty("more").GetValue(data, null);
Assert.AreEquals("something", details);
Assert.AreEquals("More", more);
}
Is there a simple way similar to this to check the anonymous properties?
[Test]
public void TestTwo()
{
var data = (dynamic) _controller.Foo().Data;
var details = data.details; // RunTimeBinderException object does not contain definition for details
var more = data.more;
Assert.AreEquals("something", details);
Assert.AreEquals("More", more);
}
Anonymous objects are internal, which means their members are very restricted outside of the assembly that declares them. dynamic respects accessibility, so pretends not to be able to see those members. If the call-site was in the same assembly, I expect it would work.
Your reflection code respects the member accessibility, but bypasses the type's accessibility - hence it works.
In short: no.
This blog had a working answer: http://blog.jorgef.net/2011/06/converting-any-object-to-dynamic.html - Thanks #Jorge-Fioranelli.
public static class DynamicExtensions {
public static dynamic ToDynamic(this object value) {
IDictionary<string, object> expando = new ExpandoObject();
foreach (PropertyDescriptor property in TypeDescriptor.GetProperties(value.GetType()))
expando.Add(property.Name, property.GetValue(value));
return expando as ExpandoObject;
}
}
Anonymous type is a regular static type in .NET, it's just that you do not give it a name (a compiler, however, does). That's why casting it to dynamic will not work. However, if you have control over Foo(), you can construct and return a dynamic object instead of anonymous, and then your code is going to work. This should do the trick:
dynamic JsonResult Foo() {
dynamic data = new ExpandoObject();
data.details = "something";
data.mode = "More";
return Json(data);
}
As suggested by #TrueWill and #Marc Gravell, who also referred to this blog post
Since this is for unit testing, you could use InternalsVisibleTo. See Anonymous Types are Internal, C# 4.0 Dynamic Beware! Thanks to #MarcGravell for pointing out that anonymous objects are internal!
Bottom line: Set up an [assembly: InternalsVisibleTo("foo")] mapping if you want to share an anonymous object from one assembly to another. In the OP case, it would be a matter of setting this in the MVC controller project, referring to the test project. In my specific case, the other way around (since I'm passing an anonymous object from my test project into the "production code" project).
The easiest way in that "other project" to be able to use it is definitely to cast it to dynamic and then just use the properties like normal. It does work, no problems whatsoever.
So, bottom line: I feel that Marc Gravell's answer is slightly incorrect; this can clearly be done
(iff the projects in question are modifiable by you, so you can set up the InternalsVisibleTo mapping accordingly, and this does not pose a problem for whatever other reason).
You can use NewtonSoft or the Asp.net MVC libraries:
var data = Json.Decode(Json.Encode(_controller.Foo().Data));
var data=JsonConvert.DeserializeObject<Dictionary<string,object>>(JsonConvert.SerializeObject((_controller.Foo().Data))

How to access a property for each memebr of an indexer using reflection in C# .net 2.0

I have the following method:
object GetIndexer()
The result of the method is an indexer of the type:
SomeCollection<T>
Now T can be anything, by I know that each T extends the type Y.
I tried casting
SomeCollection<Y> result= (SomeCollection<Y>) GetIndexer()
It didn't work.
What I need to know is how to access a property for each item in the indexer SomeCollection using Reflection?
Use GetType() for each item, then call either GetProperties() or GetProperty(propertyName) to obtain the PropertyInfo. With this, you then call GetValue() passing in your object.
An example:
List<object> objects = new List<object>();
// Fill the list
foreach (object obj in objects)
{
Type t = obj.GetType();
PropertyInfo property = t.GetProperty("Foo");
property.SetValue(obj, "FooFoo", null);
Console.WriteLine(property.GetValue(obj, null));
}
Some context would be helpful, but it sounds like you've got something like
class Foo<T> where T : Y {
object GetIndexer() { /* ... */ }
}
In that case, why not just
SomeCollection<Y> GetIndexer() { /* */ }
That way, no cast is required.
But I am a little confused by your use of the term 'indexer'. An indexer for a C# is a way of overloading the [] operator for a type, so that you can do things like:
MyCollectionType c = new MyCollectionType()
c["someValue"]
They are defined like so:
class MyCollectionType {
public string this [string index] // This particular indexer maps strings to strings, but we could use other types if we wished.
get {} // Defines what to do when people do myCollection["foo"]
set {} // Defines what to do when people do myCollection["foo"] = "bar"
}
An object of type SomeCollection<Y> isn't an indexer, it's a collection.
Is SomeCollection<T> enumerable? If so you could do
var transformed = new SomeCollection<Y>();
var someObjectCollection = (IEnumberable)GetIndexer();
foreach (var someObjectin someObjectCollection);
transformed.Add((Y)someObject);
Or wait until C# 4.0 gives us more covariance and contravariance options.
To loop through a list is the process of enumeration. It is easiest with an Enumerator. That is (in C#): anything that implements IEnumberable.
If the object you are trying to loop through is one of your own making, I recommend implementing IEnumberable. If it isn't, can you give more info about this specific 3rd party object? Maybe there are others who've also needed to use it in this way and maybe their work can be found by one of us online.

Categories