CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 9 of 9
  1. #1
    Join Date
    Aug 2006
    Posts
    22

    Smile Reflection for generics .NET 2.0

    Hello,
    I have a generic collection class.

    Code:
    public class CustomTypeCollection<T>: ICustomTypeCollection<T>, IEnumerable<T> where T:class,ICustomType, new()
        {
            
            List<T> collection=new List<T>();
       
    
            public CustomTypeCollection()
            { 
            
            }
    
            public void Add(T item)
            {
                collection.Add(item);
                
            }
    
            public T Item(int index)
            {
                return collection[index];
            }
     
            IEnumerator IEnumerable.GetEnumerator()
            {
                { return collection.GetEnumerator(); }
            }
    
           IEnumerator<T> IEnumerable<T>.GetEnumerator()
           {
               { return collection.GetEnumerator(); }
           }
    T type is not known at compile. I would like to be able to dinamically set it up at runtime. Is there a way to accomplish it nicely?

    Thank you,
    Serge
    Last edited by cjard; April 23rd, 2008 at 05:22 AM.

  2. #2
    Join Date
    Mar 2007
    Posts
    90

    Re: Reflection for generics .NET 2.0

    I wasn't able to compile CustomTypeCollection because the compiler did not find ICustomType, but still, this code should get you started as it creates an instance of CustomTypeCollection where T is a System.Int32.
    (I tested it on "public class CustomTypeCollection<T> : IEnumerable<T>"):
    Code:
    Type genericType = typeof(CustomTypeCollection<>);
    Type constructedType = genericType.MakeGenericType(Type.GetType("System.Int32", true));
    object generic = Activator.CreateInstance(constructedType);
    generic.GetType().GetMethod("Add").Invoke(generic, new object[] { 1 });

  3. #3
    Join Date
    Mar 2004
    Location
    33°11'18.10"N 96°45'20.28"W
    Posts
    1,808

    Re: Reflection for generics .NET 2.0

    you should also note that generics are not templates and are not assembled at compile time (your comment that T wasn't known at compile time prompted this comment).

  4. #4
    Join Date
    Aug 2006
    Posts
    22

    Re: Reflection for generics .NET 2.0

    Quote Originally Posted by MadHatter
    you should also note that generics are not templates and are not assembled at compile time (your comment that T wasn't known at compile time prompted this comment).
    Hello MadHatter,
    Does that mean that it's only natural to let the generic class instance know the exact type <T> just before it gets instanciated at run? Would you be able to see that process thru examinig IL modules?

    Thank you.
    Serge

  5. #5
    Join Date
    Mar 2005
    Location
    Vienna, Austria
    Posts
    4,538

    Re: Reflection for generics .NET 2.0

    Quote Originally Posted by Autofreak
    Hello MadHatter,
    Does that mean that it's only natural to let the generic class instance know the exact type <T> just before it gets instanciated at run? Would you be able to see that process thru examinig IL modules?

    Thank you.
    Serge
    I would intensify your statement and say its not only natural it is not possible to have a generic class used in code without defining T in the moment where you are using it by any code. Sure you can use a generic class in another generic code. As you did for example by using List <T> in your code. But the class itself is still generic then. But for any 'real' usage ( other then as a part of another generic class) you have to define what T exactly is. Constraints and Interfaces will help you to to a lot in your generic classes and methods, but at least the whole sense of any generic code is to use it together with nongeneric class objects
    Jonny Poet

    To be Alive is depending on the willingsness to help others and also to permit others to help you. So lets be alive. !
    Using Code Tags makes the difference: Code is easier to read, so its easier to help. Do it like this: [CODE] Put Your Code here [/code]
    If anyone felt he has got help, show it in rating the post.
    Also dont forget to set a post which is fully answered to 'resolved'. For more details look to FAQ's about Forum Usage. BTW I'm using Framework 3.5 and you ?
    My latest articles :
    Creating a Dockable Panel-Controlmanager Using C#, Part 1 | Part 2 | Part 3 | Part 4 | Part 5 | Part 6 | Part 7

  6. #6
    Join Date
    Aug 2006
    Posts
    22

    Wink Re: Reflection for generics .NET 2.0

    Quote Originally Posted by someuser77
    I wasn't able to compile CustomTypeCollection because the compiler did not find ICustomType, but still, this code should get you started as it creates an instance of CustomTypeCollection where T is a System.Int32.
    (I tested it on "public class CustomTypeCollection<T> : IEnumerable<T>"):
    Code:
    Type genericType = typeof(CustomTypeCollection<>);
    Type constructedType = genericType.MakeGenericType(Type.GetType("System.Int32", true));
    object generic = Activator.CreateInstance(constructedType);
    generic.GetType().GetMethod("Add").Invoke(generic, new object[] { 1 });
    Thank you someuser77, You solution is very helpful

    I also tried to cast 'generic' to a real class/interface in order to get the advantage of compile time and intellisense but realized that it's impossible. There is no inferitace/poltmorthysm relationship between two generic classes even if the generic types of those are in the inheritance hierarchy.


    I decided to go with a concrete collection class with List<AbstractBaseClass> in it to implement the collection functionality. I figured that I am going to use only custom classes that implement a certain behaviour 'A' anyway. This bahavior of any such class is going to be restricted by AbstractBaseClass. If anybody attempts to pass a class that doesn't inherit from AbstractBaseClass it will be disallowed at compile.


    Thank you,
    Serge

  7. #7
    Join Date
    Aug 2006
    Posts
    22

    Thumbs up Re: Reflection for generics .NET 2.0

    Quote Originally Posted by JonnyPoet
    I would intensify your statement and say its not only natural it is not possible to have a generic class used in code without defining T in the moment where you are using it by any code. Sure you can use a generic class in another generic code. As you did for example by using List <T> in your code. But the class itself is still generic then. But for any 'real' usage ( other then as a part of another generic class) you have to define what T exactly is. Constraints and Interfaces will help you to to a lot in your generic classes and methods, but at least the whole sense of any generic code is to use it together with nongeneric class objects
    Thank you, I think I got it.
    Serge

  8. #8
    Join Date
    May 2007
    Posts
    1,546

    Re: Reflection for generics .NET 2.0

    Quote Originally Posted by Autofreak
    Thank you someuser77, You solution is very helpful

    I also tried to cast 'generic' to a real class/interface in order to get the advantage of compile time and intellisense but realized that it's impossible.
    IList<T> inherits from IList, so you can cast the object to IList.

    EDIT: Sorry, just realised you weren't inheriting from IList<T>. I thought you were.
    Last edited by Mutant_Fruit; April 28th, 2008 at 01:52 PM.
    www.monotorrent.com For all your .NET bittorrent needs

    NOTE: My code snippets are just snippets. They demonstrate an idea which can be adapted by you to solve your problem. They are not 100% complete and fully functional solutions equipped with error handling.

  9. #9
    Join Date
    Mar 2004
    Location
    33°11'18.10"N 96°45'20.28"W
    Posts
    1,808

    Re: Reflection for generics .NET 2.0

    Quote Originally Posted by Autofreak
    Thank you someuser77, You solution is very helpful

    I also tried to cast 'generic' to a real class/interface in order to get the advantage of compile time and intellisense but realized that it's impossible. There is no inferitace/poltmorthysm relationship between two generic classes even if the generic types of those are in the inheritance hierarchy.


    I decided to go with a concrete collection class with List<AbstractBaseClass> in it to implement the collection functionality. I figured that I am going to use only custom classes that implement a certain behaviour 'A' anyway. This bahavior of any such class is going to be restricted by AbstractBaseClass. If anybody attempts to pass a class that doesn't inherit from AbstractBaseClass it will be disallowed at compile.


    Thank you,
    Serge
    it is actually possible.

    Code:
    public class MyClass<T> where T : /* SomeBaseClass, */ IComparable {
        T instance;
        public int Compare(T somethingElse) {
            return instance.CompareTo(somethingElse);
        }
    }
    what you need to do is define the base types that must be true for T. the syntax is:

    Code:
    where T : <param list>
    param list can be a number of things, a short list is:

    BaseClass, InterfaceA, InterfaceB, ...
    new()
    class
    struct

    so basically, you can define what T inherits (line 1) just like you would define what a class inherits: base class first if there is any, comma separated interface list

    you can specify that the type has to have a public default constructor w/ new()

    you can define that T be a reference type using the class keyword

    you can define that T be a value type by using the struct keyword.

    once you do that, you can refer to T as though it were the base class (visual studio will add in methods from the base type or interface list). if it implements new() you can say: T instance = new T(); if T implements class, you can check for null and so on...


    I hope that helps some. in the editor it feels somewhat similar to templates, but the actual implementation is quite different. when using reflection to create some generic type, if you don't specify parameters you'll end up with a null instance and it won't work. when doing things in the editor the compiler will complain if things aren't up to par.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured