I went to an interview recently and there they asked me the following question:
Write a component to travel through an object hierarchy based on the data path passed in and return the value of the property implemeting the following method:
Public object getValueFromPath(object parentObj, string dataPath);
The object hierarchy will be some thing like this:
Object1
objectRef2
property1
property2
parentObj will be Object1
dataPath will be objectRef2.property2
Can some one give me an idea how I can do that.
You would need to use reflection.
First step would be to split the dataPath on ., and get a reference to the System.Type object representing the type of parentObj (parentObj.GetType()).
Then for each element in the path you would use something like .GetMember(...) on the Type object to find the member with that name, and update the current Type object accordingly.
Once you get to the property at the end, and you have the associated ProprtyInfo object, you then need to call .GetValue(...) to get the value of the property.
Related
I'm using Newtonsoft JSON library in order to create a List<dynamic> objects:
List<dynamic> dynamics = Newtonsoft.Json.Linq.JArray.Parse(response.Content);
I want to achieve to parse each dynamic object to an AnonymousType. So in order to get that, I'm using dynamic feature of AutoMapper.
The problem is this AutoMapper feature is based on a PropertyName-based convention. So each property with the same name is mapped.
The problem I've suddently come up is a json key comment might be like: Comment, COMMENT, CoMMeNt, and so on. So, if AnonymousType has a property comment, AutoMapper won't map this. So, anonymous.comment is not equals to dynamic.CoMMeNt.
Nevertheless, Anonymous type might have a absolutly different named properties. So, anonymous.field is not equals to dynamic.comment.
I would like to map each property by order. So, first property on anotnymous type is mapped to the dynamic's first one.
How could I get that?
Create your a new base type, derived from DynamicObject that handles the naming convention you desire in the TryGetMember or similar methods. Then, when AutoMapper is calling into you object at runtime you can handle the naming issue:
public bool TryGetMember(GetMemberBinder binder, out object result)
{
string name = binder.Name.ToLower();
if (name == "comment")
{
// save comment
}
return false;
}
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.
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
I am stuck with PropertyInfo, big time. Basically it a tiny issue though idk where to start solving it. I dont usually use reflection but I need it now.
I have an object which has a property of type MyClass and MyClass futhermore holds another property. I want that last one. How do I get it?
Take a look at this:
obj.myClass.Attribute
How do I get that Attribute property by using PropertyInfo?
Use PropertyInfo.GetValue(Object):
Type type = obj.myClass.GetType();
PropertyInfo prop = type.GetProperty("Attribute");
object value = prop.GetValue(obj.myClass);
I have a class named BackUp that contains a few properties.
Let's say I have an existing instance of BackUp with its properties initialized.
As I use reflection in the BackUp class where I want to create an AgentActivator object and I need to set its properties, the idea is to retrieve the properties from the BackUp object.
The problem is to take PropertyInfo object from the BackUp object and set the matching property on the reflected object.
I am doing the following:
Assembly assembly = Assembly.LoadFile(localBackUp.AssemblyFileName);
Type currentClasstype = assembly.GetType(localBackUp.ClassName);
PropertyInfo[] properties = currentClasstype.GetProperties();
object classInstance = Activator.CreateInstance(localBackUp.AssemblyFileName,
localBackUp.ClassName);
string propName= null;
foreach(PropertyInfo prop in properties)
{
propName= prop.Name;
currentClasstype.GetProperty(propName).
SetValue(classInstance, findProperty(localBackUp, propNmae), null);
}
I need to find a way to implement the findProperty Method.
Its job is to get the string (property name) and return the matching value from the localBackUp which holds property with the propName.
From your code I assume that Type of localBackup and classInstance is the same and thus are just initializing a new class instance with the same property values another class instance (localBackup) already has try
prop.GetSetMethod().Invoke (classInstance, new object[] { prop.GetGetMethod().Invoke(localBackUp, null) } );
One remark though:
IF my assumption is true then there are IMHO much better options to do what you are trying (for example by serializing and deserializing an instance)...
If your goal is clone the object, the best (I think) approach is described here: Deep cloning objects (as #Yahia mentioned serialize and deserialize). Quite important is that it returns deep copy, so original and new object don't share data between itself.