Simple Generics - это возможный метод()? - PullRequest
1 голос
/ 27 августа 2010

Я пытаюсь создать универсальную функцию отображения, которая принимает значения словаря и его подклассов и отображает их в поля в T с помощью отражения. Внутри объекта T есть дочерние объекты, в которые нужно детализироваться, и через рекурсию это кажется довольно простой концепцией. Однако я застрял - и я не уверен, является ли это ограничением дженериков, или это что-то, что я просто делаю неправильно. Вот моя функция:

Я вызываю первый экземпляр со следующим.

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

* XmlRpcStruct - это словарь, и подклассы всегда XmlRpcStruct's - которые содержат

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

Например, я мог бы иметь словарь со следующими данными:

Key ---- стоимость

Первый - Джон

Последний раз --- Smith

Возраст ---- 45

Адресно-словарный объект

... и объект:

obj.First (строка)

obj.Last (строка)

obj.Age (int)

obj.Address (AddressType)

Я использую тип в объекте, чтобы определить, как должен быть приведен объект Dictionary из пары имя-значение.

Мне нужно иметь возможность динамически получать тип подпункта в моем словаре и рекурсивно вызывать ту же функцию. Куда я иду не так?

Ответы [ 2 ]

3 голосов
/ 27 августа 2010

Почему бы не обернуть это? В любом случае, он использует отражение ...

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;
}    
0 голосов
/ 27 августа 2010

При помощи отражения вы можете создать универсальный класс (и объект этого класса) во время выполнения, однако я не верю, что вы можете создать универсальный метод .Итак, если вы измените свой код с

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

Тогда вы сможете заставить его работать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...