Как вызвать метод расширения "ElementAt" из List <T>с отражением? - PullRequest
7 голосов
/ 22 декабря 2009

У меня проблема в том, что после создания объекта "oListType01" типа List и после присвоения его другому объекту "oObjectType" типа "object" я больше не могу получить доступ к функции "ElementAt (1)". Я попытался с помощью отражения, но я всегда получаю исключение (конфликт параметров) в методе «Invoke». Кто-нибудь знает почему? Milan

MyClass01 oMy1 = new MyClass01();
oMy1._ID = "1";

MyClass01 oMy2 = new MyClass01();
oMy2._ID = "3";

IList<MyClass01> oListType01 = new List<MyClass01>();

oListType01.Add(oMy1);
oListType01.Add(oMy2);

object oObjectType = new object();

oObjectType = oListType01;

Отсюда fowrads доступен только объект oObjectType (в реальном случае вверх происходит при отдельном вызове функции). В VS oObjectType показывает два элемента, к которым я хотел бы получить доступ для каждого отражения.

MethodInfo mInfo = typeof(System.Linq.Enumerable).GetMethod("ElementAt").MakeGenericMethod(typeof(object));
object oSingleObject = mInfo.Invoke(oObjectType, new object[] { 1 });

Ответы [ 4 ]

9 голосов
/ 22 декабря 2009

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

MethodInfo mInfo = typeof(System.Linq.Enumerable).GetMethod("ElementAt").MakeGenericMethod(typeof(MyClass01));
object oSingleObject = mInfo.Invoke(oObjectType, new object[] { oObjectType, 1 });

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

0 голосов
/ 23 декабря 2009

Это действительно похоже на ваш другой вопрос , но в этом случае статический метод ElementAt фактически требует двух параметров. Попробуйте это:

object oSingleObject = mInfo.Invoke (null, new object [] {oObjectType, 1});

0 голосов
/ 23 декабря 2009

Если мы можем с уверенностью предположить, что:

  • oObjectType является IEnumerable некоторого T

тогда вот код для извлечения предметов из него.

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

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Diagnostics;

namespace ConsoleApplication2
{
    class MyClass01
    {
        public String _ID;

        public override string ToString()
        {
            return _ID;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            MyClass01 oMy1 = new MyClass01();
            oMy1._ID = "1";

            MyClass01 oMy2 = new MyClass01();
            oMy2._ID = "3";

            IList<MyClass01> oListType01 = new List<MyClass01>();

            oListType01.Add(oMy1);
            oListType01.Add(oMy2);

            object oObjectType = new object();

            oObjectType = oListType01;

            Test(oObjectType);

            Console.In.ReadLine();
        }

        private static void Test(object oObjectType)
        {
            Type tObject = oObjectType.GetType();
            Debug.Assert(tObject.IsGenericType);
            Debug.Assert(tObject.GetGenericArguments().Length == 1);
            Type t = tObject.GetGenericArguments()[0];

            Type tIEnumerable = typeof(IEnumerable<>).MakeGenericType(t);
            Debug.Assert(tIEnumerable.IsAssignableFrom(tObject));

            MethodInfo mElementAt =
                typeof(Enumerable)
                .GetMethod("ElementAt")
                .MakeGenericMethod(t);

            Console.Out.WriteLine("o[0] = " +
                mElementAt.Invoke(null, new Object[] { oObjectType, 0 }));
            Console.Out.WriteLine("o[1] = " +
                mElementAt.Invoke(null, new Object[] { oObjectType, 1 }));
        }
    }
}
0 голосов
/ 22 декабря 2009

Метод расширения ElementAt, вероятно, используется в IEnumerable , и поэтому, когда вы обрабатываете свой список как объект, метод расширения не будет доступен, пока вы его не приведете. Либо ((List ) oObjectType) .ElementAt (), либо (oObjectType as List ). ElementAt ().

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

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