簡體   English   中英

如何使用運行時類型A轉換集合:IList <AT> 進入類型B的新集合:IList <BT> 使用反射?

[英]How to transform collection with runtime type A: IList<AT> into a new collection of type B: IList<BT> using reflection?

關於編譯時的類型一無所知。

object TransformObject(object oldObject, Type newType, Func<object, object> transform)
{
    if(obj.GetType().ImplementsGenericInterface(typeof(IList<>))
    && newType.ImplementsGenericInterface(typeof(IList<>)))
    {
        object newCollection = Activator.CreateInstance(newType);

        // This is where it gets tricky:
        // 1. How to iterate over the old collection?
        // 2. How to add each element in the new collection?
        object oldCollection = oldObject as IEnumerable;
        foreach(var oldItem in oldCollection)
        {
            object newItem = transform(oldItem);
            newCollection.Add(newItem);
        }

        // 3. How to ensure that the order in the new collection is preserved?

        return newCollection;
    }

    return null;
}

自然這是行不通的。

在運行時已知:

  • oldCollection.GetType()實現類型IList<AT>
  • newType實現類型IList<BT>
  • 函數object transform(object oldObject)負責將AT類型的對象轉換為BT類型的新對象。 或將對象映射到不同類型的對象。 映射是未知的編譯時。

試試這個解決方案:

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;


public class Test
{
    static bool ImplementsGenericInterface(Type type, Type genericInterface)
    {
        return type.GetInterfaces().Any(i => i.GetGenericTypeDefinition() == genericInterface);
    }

    static object TransformObject(object oldObject, Type newType, Func<object, object> transform)
    {
        if (ImplementsGenericInterface(oldObject.GetType(), typeof(IList<>))
           && ImplementsGenericInterface(newType, typeof(IList<>)))
        {
            object newCollection = Activator.CreateInstance(newType);
            var method = newType.GetMethod("Add");

            foreach (var item in (IEnumerable)oldObject)
            {
                var newItem = transform(item);
                method.Invoke(newCollection, new object[] { newItem });
            }

            return newCollection;
        }

        return null;
    }

    public static void Main()
    {
        var list1 = new List<int>() { 1, 2, 3 };

        var list2 = (List<string>)TransformObject(list1, typeof(List<string>), o => o.ToString());

        foreach (var item in list2)
            Console.WriteLine(item);

        Console.ReadKey();
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM