как динамически привести IList к массиву произвольного типа данных, используя Reflection - PullRequest
2 голосов
/ 27 марта 2020
class myClass1
{
    public string obj1;
    public string obj2;

}
class myClass2
{
    public myClass1[] fArray = new myClass1[1];
    public string str;
}
class Program
{
    static void Main(string[] args)
    {
        string mytype = "ConsoleApp3.myClass2";
        Type type = Type.GetType(mytype);
        object myObj = Activator.CreateInstance(type);
        FieldInfo fi = type.GetField("fArray");
        Type type2 = fi.FieldType.GetElementType();
        object newObj;
        IList list = (IList)Activator.CreateInstance(typeof(List<>).MakeGenericType(fi.GetValue(myObj).GetType().GetElementType()));
        {
            newObj = Activator.CreateInstance(type2);
            FieldInfo fi2 = type2.GetField("obj1");
            fi2.SetValue(newObj, "some txt1");
            FieldInfo fi3 = type2.GetField("obj2");
            fi3.SetValue(newObj, "some txt2");
            list.Add(newObj);
        }

        {
            newObj = Activator.CreateInstance(type2);
            FieldInfo fi2 = type2.GetField("obj1");
            fi2.SetValue(newObj, "some txt1");
            FieldInfo fi3 = type2.GetField("obj2");
            fi3.SetValue(newObj, "some txt2");
            list.Add(newObj);

        }

        fi.SetValue(myObj, list.Cast<myClass1>().ToArray());

Код выше работает нормально. В моем случае "myClass1" не знаю во время компиляции. Я получаю тип myClass1 в виде строки во время выполнения.

Как я могу привести список к массиву типа myClass1, используя отражение?

        fi.SetValue(myObj, list.Cast<???>().ToArray());

Ответы [ 2 ]

1 голос
/ 27 марта 2020

Вы также можете создавать обобщенные c методы:

Давайте создадим локальную переменную для типа элемента, чтобы мы могли ее повторно использовать.

var elementType = fi.GetValue(myObj).GetType().GetElementType();
...

Получить метод приведения и массив метод из перечислимого класса linq.

var castMethod = typeof(System.Linq.Enumerable).GetMethod("Cast").MakeGenericMethod(elementType);
var arrayMethod = typeof(System.Linq.Enumerable).GetMethod("ToArray").MakeGenericMethod(elementType);

Вызовите методы с нулевым значением в качестве первого аргумента для методов stati c.

var casted = castMethod.Invoke(null, new[] { list });
var array = arrayMethod.Invoke(null, new[] { casted });
fi.SetValue(myObj, array);

Может быть более разумный способ сделать это , но это может начать вас.

0 голосов
/ 27 марта 2020

Type.GetType и Type.MakeArrayType приходит к вам на помощь.

Вы можете сделать:

Type t = Type.GetType("myString");

или

Type arrayT = Type.GetType("myString").MakeArrayType() ;

В вашем примере GetType будет достаточно, но также полезно знать и о MakeArrayType.

...