I am attempting to create a generic mapping function that takes the values of a dictionary and its sub classes and maps them to the fields in T using reflection. Within object T, there are sub objects that must be drilled into, and through recursion, it seems like a pretty simple concept. Howe开发者_如何学Gover I am stuck -- and I'm not sure if it's a limitation of generics, or if it's something I am simply doing wrong. Here's my function:
I call the first instance with the following.
OrderDetails readyOrder = Tools.MapStruct<OrderDetails>(order);
*XmlRpcStruct is a dictionary, and the sub classes are always XmlRpcStruct's -- which conta
public static T MapStruct<T>(XmlRpcStruct xmlRpcStruct) where T : new()
{
T map = new T();
foreach (DictionaryEntry entry in xmlRpcStruct)
{
XmlRpcStruct entryStruct = (XmlRpcStruct)entry.Value;
foreach (DictionaryEntry subEntry in entryStruct)
{
if (subEntry.Value.GetType() != typeof(XmlRpcStruct))
{
var prop = map.GetType().GetField(subEntry.Key.ToString());
prop.SetValue(map, subEntry.Value);
}
else
{
var prop = map.GetType().GetField(subEntry.Key.ToString());
ERROR -->prop.SetValue(map, MapStruct<prop.GetType()> (subEntry.Value));
}
}
}
return map;
}
For example, I could have a dictionary with the following data:
Key----Value
First--John
Last---Smith
Age----45
Address-Dictionary Object
...and an object:
obj.First (string)
obj.Last (string)
obj.Age (int)
obj.Address (AddressType)
I'm using the type in the object to determine what the Dictionary object from the name value pair should be cast as.
I need to be able to dynamically get the type of the sub item within my dictionary and recursively call the same function. Where am I going wrong?
Why not wrap it? It's using reflection anyway...
public static T MapStruct<T>(XmlRpcStruct xmlRpcStruct) where T : class, new()
{
return (T)MapStructInternal(typeof(T), xmlRpcStruct);
}
private static object MapStructInternal(Type t, XmlRpcStruct xmlRpcStruct)
{
object map = t.GetConstructor(new Type[0] ).Invoke(new object[0]);
foreach (DictionaryEntry entry in xmlRpcStruct)
{
XmlRpcStruct entryStruct = (XmlRpcStruct)entry.Value;
foreach (DictionaryEntry subEntry in entryStruct)
{
if (subEntry.Value.GetType() != typeof(XmlRpcStruct))
{
var prop = map.GetType().GetField(subEntry.Key.ToString());
prop.SetValue(map, subEntry.Value);
}
else
{
var prop = map.GetType().GetField(subEntry.Key.ToString());
prop.SetValue(map, MapStructInternal(map.GetType(),(XmlRpcStruct)subEntry.Value));
}
}
}
return map;
}
Throught Reflection, you can create a generic class (and an object of the class) at runtime, however, I don't believe you can create a generic method. SO, if you change you code from
public static T MapStruct<T>(XmlRpcStruct xmlRpcStruct) where T : new() {...}
to
static class Mapper<T> where T : new()
{
public T MapStruct(XmlRpcStruct xmlRpcStruct) {....}
}
var mapper = new Mapper<OrderDetails>();
OrderDetails readyOrder = mapper.MapStruct<OrderDetails>(order);
Then you should be able to make it work.
精彩评论