7

I have problem that after creating object "oListType01" of type List < MyClass01 > and after assigning it to the another objet "oObjectType " of type "object" I can not access any more function "ElementAt(1)". I tried by using reflection but I am always getting exception(parameter conflict) in "Invoke" method. Does anyone knows why ? 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;

From here fowrads only object oObjectType is available (upwards happens in separate function call in the real case). In VS oObjectType shows two element which I would like to access per reflection.

MethodInfo mInfo = typeof(System.Linq.Enumerable).GetMethod("ElementAt").MakeGenericMethod(typeof(object));
object oSingleObject = mInfo.Invoke(oObjectType, new object[] { 1 });
abatishchev
  • 98,240
  • 88
  • 296
  • 433
milan
  • 133
  • 2
  • 6
  • Why are you assigning it to an object in the first place? If you have to for some reason, and if you know at compile-time what type that the list is always going to contain MyClass01 instances, why don't you just cast it back to a List, like this: ((List)oObjectType).ElementAt(1); – tclem Dec 22 '09 at 19:19
  • plese take a look at "answer" where I explained that in invoke can be used only reference to the oObjectType (not oListType01 and not MyClass01). – milan Dec 23 '09 at 11:11

4 Answers4

9

I will assume you have a valid reason to be doing this but it seems a little wrong. That said here is some code that will accomplish what you are trying to do.

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

When I run this code I get the second element in the List.

Shaun Bowe
  • 9,840
  • 11
  • 50
  • 71
  • plese take a look at "answer" where I explained that in invoke can be used only reference to the oObjectType (not oListType01) . – milan Dec 23 '09 at 11:11
  • I changed the code so it invokes on the reference. That should do it. – Shaun Bowe Dec 23 '09 at 15:00
  • This worked for me, thanks! Just one note: the first parameter to mInfo.Invoke() can be null. We're calling a static method, not a method on an instance method. – Ryan Kirkman Jul 25 '12 at 23:38
0

The ElementAt extension method is probably on IEnumerable<T> and so when you treat your list like an object, the extension method won't be available unless you cast it. Either ((List<MyClass01>)oObjectType).ElementAt() or (oObjectType as List<MyClass01>).ElementAt().

I have to ask, though, with all due respect why you'd ever want to do this in the first place? It strikes me that there's something wrong here that could be done a little cleaner using interfaces.

D. Patrick
  • 2,894
  • 26
  • 37
0

If we can safely assume that:

  • oObjectType is a IEnumerable of some T

then here's the code to extract the items from it.

Note that I seriously wonder if this is the right way to go about this, but you haven't given us enough information to help you figure out if there's a better way, so all we're left with is just answering the question as asked.

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 }));
        }
    }
}
Lasse V. Karlsen
  • 380,855
  • 102
  • 628
  • 825
0

This is really similar to your other question, but in this case, the static ElementAt method is actually requiring two parameters. Try this:

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

Community
  • 1
  • 1
Rob Fonseca-Ensor
  • 15,510
  • 44
  • 57