How to fill a generics List with reflection?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • =?Utf-8?B?TXJOb2JvZHk=?=

    #1

    How to fill a generics List with reflection?

    Say I have a class that has a generics List as follows:

    public List<MyClassmyC lassList = new List<MyClass>() ;

    and I want to create another class which tries to add an element of MyClass
    to that list, but it is not explicitly creating an instance of MyClass, but
    instead using the Activator to create an instance based on it's type name.

    How can I accomplish this in C# using reflection?



  • Ignacio Machin ( .NET/ C# MVP )

    #2
    Re: How to fill a generics List with reflection?

    On May 13, 2:30 pm, MrNobody <MrNob...@discu ssions.microsof t.com>
    wrote:
    Say I have a class that has a generics List as follows:
    >
    public List<MyClassmyC lassList = new List<MyClass>() ;
    >
    and I want to create another class which tries to add an element of MyClass
    to that list, but it is not explicitly creating an instance of MyClass, but
    instead using the Activator to  create an instance based on it's type name.
    >
    How can I accomplish this in C# using reflection?
    I don't see where is the problem, you can invoke your Add either by
    reflection or simply casting the instance resulting of using Activator
    to the correct type.
    Or you can use Activator to create an instance of MyClass and then use
    InvokeMember with the created instance

    Comment

    • Peter Duniho

      #3
      Re: How to fill a generics List with reflection?

      On Tue, 13 May 2008 11:30:00 -0700, MrNobody
      <MrNobody@discu ssions.microsof t.comwrote:
      Say I have a class that has a generics List as follows:
      >
      public List<MyClassmyC lassList = new List<MyClass>() ;
      >
      and I want to create another class which tries to add an element of
      MyClass
      to that list, but it is not explicitly creating an instance of MyClass,
      but
      instead using the Activator to create an instance based on it's type
      name.
      >
      How can I accomplish this in C# using reflection?
      Well, you said you're already using Activator. So isn't that using
      reflection?

      Once you've got an instance of MyClass, it doesn't matter how you got it..
      You can add it to a List<MyClasswhe ther you used "new" or Activator.
      So, if you're having problems adding the instance to your list, it's
      because you're not creating the type you apparently think you are.

      You should post a concise-but-complete code sample that demonstrates the
      problem you're having. Make sure you're specific about what fails.

      Pete

      Comment

      • =?Utf-8?B?TXJOb2JvZHk=?=

        #4
        Re: How to fill a generics List with reflection?



        "Peter Duniho" wrote:
        >
        You should post a concise-but-complete code sample that demonstrates the
        problem you're having. Make sure you're specific about what fails.
        >
        Pete
        >
        Ok, here is a good test case to demonstrate what I am talking about:

        public class MainClass
        {
        public void Test()
        {
        ParentClass parent = new ParentClass();
        Console.WriteLi ne(parent.myCla ssList.Count + " items");

        Type listType = Type.GetType("T ools.MyClass");
        List<listTypeli st = parent.GetType( ).GetField("myC lassList");
        // the type or namespace name 'listType' could not be found
        list.Add(Activa tor.CreateInsta nce(listType)); // compiler error:
        cannot convert form object to 'listType'

        Console.WriteLi ne(parent.myCla ssList.Count + " items");

        }
        }

        public class ParentClass
        {
        public List<MyClassmyC lassList = new List<MyClass>() ;
        }

        public class MyClass
        {
        public string testString = "";
        }

        See how do I make a generic reference of that List? I think in Java you can
        do something like List<?so you dont need to explicitly specify type but I
        cant figure out how to do it in C#.

        See I need to get a reference to that List using reflection without
        explicitly specifying it's type, since it's type could be anything. Then I
        need to add a new instance of that type to the list, again without explicitly
        specifying it's type.

        It has to be completely dynamic so that I can create an instance of a user
        specified type and Add it to a List of that type.

        Comment

        • Peter Duniho

          #5
          Re: How to fill a generics List with reflection?

          On Tue, 13 May 2008 12:39:01 -0700, MrNobody
          <MrNobody@discu ssions.microsof t.comwrote:
          [...]
          See how do I make a generic reference of that List? I think in Java you
          can
          do something like List<?so you dont need to explicitly specify type
          but I
          cant figure out how to do it in C#.
          I don't think you can do this in Java either. "List<?>" is sort of like
          "List<T>" in C# where T is a type parameter, but in either case it's a
          compile-time thing used to declare a generic. When you _use_ a generic,
          there has to be a real type there.

          Do you really need your collection to be in a List<T>? Again, since the
          main benefit of generics is a compile-time thing, if you don't know the
          type at compile time, it's not clear why you want to use List<T>.

          In this particular example, I would just use an ArrayList, which is an
          untyped collection that otherwise behaves similar to List<T>.

          If you think that you really need a List<There, it would be helpful if
          you could elaborate on that, including presenting a code example that
          actually demonstrates that requirement. To do what you're asking
          literally I believe would at a minimum require using reflection again,
          instantiating the specific List<Tusing Activator or similar, and then
          using reflection to invoke the appropriate Add() method.

          But it seems to me that there's a strong likelihood that there's not
          really a literal need to use List<T>. If you can provide a better
          question, it's like you'll get a better answer, including an explanation
          of an alternative approach that doesn't require reflection at all for the
          collection itself.

          Pete

          Comment

          • Chris Shepherd

            #6
            Re: How to fill a generics List with reflection?

            MrNobody wrote:
            See how do I make a generic reference of that List? I think in Java you can
            do something like List<?so you dont need to explicitly specify type but I
            cant figure out how to do it in C#.
            List<T>. From your description I don't even think you need reflection.

            Something like:

            private void AddNewTolist<T> (List<TtoList)
            {
            if (toList != null)
            toList.Add(new T());
            }

            Maybe I'm wrong, I don't have access to VS atm.

            Chris.

            Comment

            • Marc Gravell

              #7
              Re: How to fill a generics List with reflection?

              Generics:

              public void Test()
              {
              ParentClass parent = new ParentClass();
              Console.WriteLi ne(parent.myCla ssList.Count + " items");
              Foo(parent.myCl assList);
              Console.WriteLi ne(parent.myCla ssList.Count + " items");
              }
              public void Foo<T>(List<Tli st) where T : new() {
              list.Add(new T());
              }

              Marc

              Comment

              • Jon Skeet [C# MVP]

                #8
                Re: How to fill a generics List with reflection?

                MrNobody <MrNobody@discu ssions.microsof t.comwrote:
                You should post a concise-but-complete code sample that demonstrates the
                problem you're having. Make sure you're specific about what fails.
                >
                Ok, here is a good test case to demonstrate what I am talking about:
                <snip>

                Looks to me like ParentClass should be generic, at which point half the
                problems go away.

                Most of the point of generics is to give *compile-time* type safety. If
                you're not going to get that benefit, you'll probably find it's easier
                just to use ArrayList rather than messing around with reflection.

                --
                Jon Skeet - <skeet@pobox.co m>
                Web site: http://www.pobox.com/~skeet
                Blog: http://www.msmvps.com/jon.skeet
                C# in Depth: http://csharpindepth.com

                Comment

                Working...