"Name" array after a string c# [duplicate] - c#

I'm working on a deserialization class in .NET, I have to develop a method that provides to me with a variable name that is stored in a string.
I have a string such as:
string string_name = "this_is_going_to_be_var_name";
Now what can I do so that my code dynamically declares a variable named this_is_going_to_be_var_name?
So to clear things up: There will be a deserialization class that will declare variables of the same names as strings provided as input with their PARENT TYPES as per wish of the Higher Level Programmer/User.
For Example: In javascript/jQuery, when I fetch JSON by making a request, the interpreter declares variable(s)/array(s) of the same name and assigns values to them. If {"var_name":"var_value"} is a JSON string, the interpreter will create a variable named var_name and will assign "var_value" to it such as json_data_object.var_name.

No you can't. C# variables are all statically declared.
The best thing you can do is create a dictionary and use keys instead of variable names.
// Replace object with your own type
Dictionary<string, object> myDictionary = new Dictionary<string, object>();
myDictionary.Add("this_is_going_to_be_var_name", value_of_the_variable);
// ...
// This is equivalent to foo($this_is_going_to_be_var_name) in PHP
foo(myDictionary["this_is_going_to_be_var_name"]);

This isn't possible, variable names are defined at compile time, not run time.
One approach is to create a dictionary or hash table to map string names to objects to sort of achieve what you want.

Not sure what you meant by
my code dynamically declares a variable named
this_is_going_to_be_var_name?
but the .Net version of what explode does in PHP is Split:
string[] zz = "this_is_going_to_be_var_name".Split('_');

The only thing that I can think on the moment (I haven't tested it so I have no clue if it is possible), is to have a object of type dynamic and then try to set the fields at runtime using reflection and InvokeMember(), which I can give a chance that it will work since the there is no validation on objects of type dynamic.
UPDATE:
I have tested it with ExpendoObject and InvokeMember doesn't appear to work (at least not with the default binder, but I haven't tested it with DynamicObject and allthough I don't give it to much chances to work you might still try it, you can check out http://msdn.microsoft.com/en-us/library/ee461504.aspx on how to use DynamicObject.
Take a look on Dynamically adding properties to an ExpandoObject which essentially describes a method in which the dynamic object is being cast as a IDictionary and then you can add properties to it by using the standard dictionary access, while they are actually getting properties of the object.
I tested it in a sample project by having a dynamic object of type ExpendoObject and then I add another variable that referenced it using type IDictionary, and then I tried to set and get properties on both, as in the following example:
dynamic test = new ExpandoObject();
//reference the object as a dictionary
var asDictinary = test as IDictionary<string, Object>;
//Test by setting it as property and get as a dictionary
test.testObject = 123;
Console.Write("Testing it by getting the value as if it was a dictionary");
Console.WriteLine(asDictinary["testObject"]);
//Test by setting as dictionary and get as a property
//NOTE: the command line input should be "input", or it will fail with an error
Console.Write("Enter the varible name, ");
Console.Write("note that for the example to work it should the word 'input':");
string variableName = Console.ReadLine();
Console.Write("Enter the varible value, it should be an integer: ");
int variableValue = int.Parse(Console.ReadLine());
asDictinary.Add(variableName, variableValue);
Console.WriteLine(test.input);//Provided that the command line input was "input"
(Still however in your case since you will anyway not access the properties directly in code I don't see the need for it and you would probably be able to use a Dictionary directly, and I don't understand why you need them to be properties of the object, which is only needed if you want to reference them at compile time.
But maybe I am misunderstanding you and you are looking for a dynamic variable and not for a dynamic property [something that is available in PHP using the $$ syntax], if this is the case then note that in c# there are no variables at all as everything is encapsulated in a object).
You can also take a look in How can I dynamically add a field to a class in C# for more answers.

Related

Use reflection to get actual return type form Task<List<Dictionary<string,object>>> instead of object

I am trying to get the actual object that is contained within a list that itself is contained within a task.
e.g. method has the following signature e.g.
public async Task<List<Dictionary<string,object>>> GetData()
i am currently using something like this:
var member = type.GetMembers()[0];
var returntype = member.ReturnType.GetGenericArguments();
var temp = member.ReturnType.GetGenericArguments()[0];
if (temp.GetGenericArguments().Count() > 0)
{
temp.GetTypeInfo().GetGenericArguments();
var innerttype = temp.GetGenericArguments()[0].FullName;
}
Currently the above code (which is not complete but just an extract from actual code) return system.object as fullname instead of Dictionary.
Any suggestions to solve this are welcome.
If you declare your dictionary to be of type <string, object> and and only ever insert objects inside it and not something higher up in the graph, you'll only ever get object typed objects out of it.
If you're storing all kinds of things in there and need to get their concrete type so you can interact with them, try to make them all conform to an interface first. Then, put the interface type in there replacing "object." If that doesn't work you can use generics. However, you'll still need to know the type ahead of time in order to be able to interact with it.
If you really have no idea what's in there and want to dig into it dynamically, that's precisely what Reflection was built for. You could also look into the dynamic type.

Creating a specific type of object chosen from a set of types obtained through reflection

I'm essentially coding an interface for a user to create instances of different classes. I'm using winforms so that if the code says the class has a property of type int, it provides a numbox, a check box for bool, etc. The form is generated at runtime and the controls shown depends on the number and type of the properties in the class being reflected upon.
I need to take the values the user inputs and create an object with the properties set to those values. The issue is that the number and types of the properties is different for each object. What I'd like is some way to do the following:
Object o = new Object(property1, property2)
Where Object would be replaced by whatever class is currently being used and the parameters are replaced with the values from the winform controls in the appropriate quantity.
The type that the class could be is limited to a finite list, and each class has a constructor in the style above. All classes have at least one property to set.
List<object> parms = new List<object>();
parms.Add(property1);
parms.Add(property2);
ObjectHandle objHandle = Activator.CreateInstance("assemblyName", "className", false, null, null, parms.ToArray(), null, null );
object workingObject = objHandle.Unwrap();
Replace "assemblyName" with your assembly's name and "className" with the fully-qualified name of your class.
This should give you the flexability to create an instance of any class with any number of constructor parameters.
from what i understand,
you need to have a factory class that will create and assign the properties
Following info may help.
to the factory class method you need to pass the following info
type of class/control needed ( as you mentioned int or bool, any thing is fine as long as your factory class understands this logic)
i.e it can create the control needed either by reflection or by simply instantiating the class
for passing the properties info i suggest to have a dictionary of type string,object
.string will store the property name as key and Object as its value
for assigning the properties values, you loop through this dictionary
and assign values using reflection as shown in the below sample
Type type = control.GetType();
PropertyInfo prop = type.GetProperty("propertyName");
prop.SetValue (control,propertyValue, null);
if my understanding is not right, please add more info on your question in the comments

Can I dynamically create a property type and property name for an object?

Can I dynamically create a property type and property name for an (anonymous) object if the name and type I get from a string variable?
If you're talking about anonymous types (such as var x = new { Property1 = data1, ...}) then I don't think that you can.
What you might be able to do is create another new anonymous type from the one you already have. Where you want to create Y from X, you could create Y by var Y = new { YProp1 = X.Prop1, YProp2 = X.Prop2, etc}
In c# 4.0 onwards you can use dynamic keyword with DynamicObject object based on dictionary to create/extend properties at runtime very much like JavaScript.
For anonymous classes, no. These are defined at compile-time by the compiler.
C# .NET is a statically typed language, meaning that all classes must be defined at compile time. So, the knee-jerk answer to your question is no.
However, like most languages, there are workarounds that you can use. For instance, you can create a class that has a Dictionary<string,object> type property that will take your property names as keys and your property values as values.
Of course, the downside to this is that you will need to write extra code to verify that the data in the dictionary is valid... so it may not be worth it.

C# - Get property in member class using Reflection

SHORT VERSION
What's the best way to use reflection to turn something like string prop = "part1.first_name"; into a System.Reflection.PropertyInfo, so that I can use the GetValue and SetValue functions?
LONG VERSION
I'm using ASP .NET MVC to build a questionnaire for my organization. It's very long, so it's divided into several different pages. Since it's not uncommon for us to get requests like, "Can you move this question to that page, and this other question to another page," I need to build this to be pretty flexible for a junior programmer to change.
My model is a complex class (it's got five member classes that have mostly primitive-typed properties on them).
So, I access it by doing things like Model.part1.first_name or Model.part2.birth_date.
Since the same model is used on all of the pages, but not all of the questions are on every page, I have ActionAttributes that essentially clear out all of the properties that were submitted on the form except for the ones that were displayed on that page (so someone can't inject a hidden field into the form and have the value persist to the database).
I want to make sure that I only save valid field values and don't let the user proceed to the next page until the current one is entirely OK, but I also want to save the values that are valid, even if the user isn't allowed to proceed.
To do this, I have a function that takes two instances of my model class, a reference to the ModelStateDictionary, and a string[] of field names like "part1.first_name" and "part2.birth_date". That function needs to copy all of the values listed in the string array that do not have validation errors from the first (ie, form-submitted) object into the second (ie, loaded from the db) object.
As stated above, what's the best way to use reflection to turn something like "part1.first_name" into a System.Reflection.PropertyInfo, OR, is there a better way to accomplish this?
var infoParts = prop.Split('.');
var myType = Type.GetType(infoParts[0]);
var myPropertyInfo = myType.GetProperty(infoParts[1]);
Assuming "part1" is your type. Although this is very limited and very dependent on the string being in the correct format and the type being in the current scope.
I would probably handle this differently, using data. I would keep, in the database, which step each question belongs to. To render that step, I would select the questions that match that step and have a model that contains a list of question id/question pairs. Each input would be identified by the question id when posted back. To validate, simply compare the set of question ids with the expected ids for that step. This way, to change which question goes in which step is to only change the data in the database.
If you do end up going down that road, you'll need to split the string into parts and recursively or iteratively find the property on the object at each step.
PropertyInfo property = null;
Type type = questionModel.GetType();
object value = questionModel;
object previousObj = null;
foreach (var part in questionId.Split('.'))
{
property = type.GetProperty(part);
previousObj = value;
value = property.GetValue(value,null);
type = value.GetType();
}
// here, if all goes well, property should contain the correct PropertyInfo and
// value should contain that property's value...and previousObj should contain
// the object that the property references, without which it won't do you much good.

Instantiating anonymous object using C# object initializer syntax stored in string

Using the C# object initializer syntax I can instantiate an anonymous object like this:
object empData = new { name = "bob", age = 30, salary = 100000 };
But what if I have the initializer stored in a string, e.g.:
string init = "{ name = \"bob\", age = 30, salary = 100000 }";
Whats the best way of converting this string into an instance of the object?
Anonymous classes are C# syntactic sugar (see Remarks section here). csc.exe creates a class with private fields and a read/write property with the type inferred from context. All uses of the object are, again, inferred.
What this means is you cannot create an anonymous class at run time because the CLR sees them no differently than any other class (again, because it is C# syntactic sugar).
So instead:
Use a Dictionary<string,object>
Use JSON.NET, XML or something like it that has some already-defined scheme for parsing a string to get an object. This requires the properties be well-defined, however.
Use System.Reflection.Emit to create the type at run-time, but I see no real benefit to this over just a Dictionary<string,object>
I also have concerns of what you're doing because this as a string very likely means to me that you are accepting user input of some kind. Be wary of the security issues in whatever you do.
It's not possible using anonymous types, however you can do it with Reflection Emit using the TypeBuilder class, specifically TypeBuilder.Create(..).
http://msdn.microsoft.com/en-us/library/system.reflection.emit.typebuilder.createtype.aspx
The best way to do it is to use serialization. But of course, that doesn't use the same string format that you described.
Your object initializer does not have to contain constant values.
string myName="bob";
int myAge=30;
double mySalary=100000;
object empData = new { name = myName, age = myAge, salary = mySalary };
So in your scenario you would have to parse out the individual elements from your string, and perform some conversions on them to coerce them into the types you want.
If you are not married to this particular string format, you can serialize and deserialize your objects and accomplish the same thing using XML much more easily.
There's no direct easy way to do so. Basically, you have these options:
Parse the string manually.
Use the C# compiler to compile that object as a part of an assembly and use reflection to figure out the contents.
(not sure if it's possible, C# 4.0 only): Use C# 4.0 managed compiler classes to parse the expression and infer the stuff.
None of which is ideal in my opinion. I'd consider QueryString like pairs, XML or JSON or some other format that has parsers available out there instead if you have the option and consider storing data in a dictionary instance instead of creating an object for every expression.
I don't think this question answers yours per se, but it will tell you why it's not possible to create anonymous instances of objects using strings in a manner such as you suggest:
How do I create and access a new instance of an Anonymous Class passed as a parameter in C#?
Anonymous types don't have any public fields, consequently while you can do this for a named object, it's not so simple to do it for an anonymous type. That said, there's nothing to stop you [as suggested by BFree] using reflection to emit the MSIL for the anonymous type - which isn't exactly straightforward, but isn't impossible either.

Categories