简单的泛型 - 这可能是方法<typeof(t)>()?</typeof(t)>

时间:2010-08-26 20:48:27

标签: c# generics reflection recursion

我正在尝试创建一个通用映射函数,它接受字典及其子类的值,并使用反射将它们映射到T中的字段。在对象T中,必须钻入子对象,并且通过递归,它看起来像一个非常简单的概念。然而,我被困 - 我不确定它是否是泛型的限制,或者如果它是我只是做错了。这是我的功能:

我用以下内容调用第一个实例。

OrderDetails readyOrder = Tools.MapStruct<OrderDetails>(order);

* XmlRpcStruct是一个字典,子类总是 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;
    }

例如,我可以使用包含以下数据的字典:

关键----值

首先约翰 -

最后---史密斯

年龄---- 45

地址 - 字典对象

...和一个对象:

obj.First(string)

obj.Last(string)

obj.Age(int)

obj.Address(AddressType)

我正在使用对象中的类型来确定名称值对中的Dictionary对象应该被强制转换为。

我需要能够动态获取字典中子项的类型并递归调用相同的函数。我哪里错了?

2 个答案:

答案 0 :(得分:3)

为什么不包装它?无论如何它都在使用反射......

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;
}    

答案 1 :(得分:0)

反射,你可以在运行时创建一个通用的(和类的对象),但是,我不相信你可以创建一个通用的方法 。所以,如果你改变你的代码

 public static T MapStruct<T>(XmlRpcStruct xmlRpcStruct) where T : new()  {...}

 static class Mapper<T> where T : new() 
 {
      public T MapStruct(XmlRpcStruct xmlRpcStruct) {....}
 }

  var mapper = new Mapper<OrderDetails>();
  OrderDetails readyOrder = mapper.MapStruct<OrderDetails>(order);  

然后你应该能够使它发挥作用。