Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. How to instantiate an object with a generic parameter?

How to instantiate an object with a generic parameter?

Scheduled Pinned Locked Moved C#
tutorialquestionhelp
12 Posts 6 Posters 2 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    M Offline
    michal kreslik
    wrote on last edited by
    #1

    Hello, I can't figure this one out, so I'll be happy if someone lends me a helping hand here. How do I instantiate an object with a generic type parameter if I don't know what the type parameter will be at run time? Example:

    namespace GenericTypeInitialization
    {
    class Program
    {
    static void Main()
    {
    Console.WriteLine("Press 1 for FooA, press 2 for FooB:");
    ConsoleKeyInfo key = Console.ReadKey(true);

            Type TypeOfFoo;
    
            if (key.KeyChar == '1')
            {
                Console.WriteLine("FooA selected.");
                TypeOfFoo = typeof(FooA);
            }
            else if (key.KeyChar == '2')
            {
                Console.WriteLine("FooB selected.");
                TypeOfFoo = typeof(FooB);
            }
    
            ////
            Bar<TypeOfFoo> MyInstanceOfBar = new Bar<TypeOfFoo>();
        }
    }
    
    class FooA {}
    
    class FooB {}
    
    class Bar<TFoo> {}
    

    }

    Obviously, the above code doesn't compile. I'm getting an error of The type or namespace name 'TypeOfFoo' could not be found (are you missing a using directive or an assembly reference?) How do I get the type parameter at run time then? I've tried various things, but none worked. Also, you can't instantiate the Bar<> class before '////'. Thanks a lot for any input, Michal

    G E L D M 5 Replies Last reply
    0
    • M michal kreslik

      Hello, I can't figure this one out, so I'll be happy if someone lends me a helping hand here. How do I instantiate an object with a generic type parameter if I don't know what the type parameter will be at run time? Example:

      namespace GenericTypeInitialization
      {
      class Program
      {
      static void Main()
      {
      Console.WriteLine("Press 1 for FooA, press 2 for FooB:");
      ConsoleKeyInfo key = Console.ReadKey(true);

              Type TypeOfFoo;
      
              if (key.KeyChar == '1')
              {
                  Console.WriteLine("FooA selected.");
                  TypeOfFoo = typeof(FooA);
              }
              else if (key.KeyChar == '2')
              {
                  Console.WriteLine("FooB selected.");
                  TypeOfFoo = typeof(FooB);
              }
      
              ////
              Bar<TypeOfFoo> MyInstanceOfBar = new Bar<TypeOfFoo>();
          }
      }
      
      class FooA {}
      
      class FooB {}
      
      class Bar<TFoo> {}
      

      }

      Obviously, the above code doesn't compile. I'm getting an error of The type or namespace name 'TypeOfFoo' could not be found (are you missing a using directive or an assembly reference?) How do I get the type parameter at run time then? I've tried various things, but none worked. Also, you can't instantiate the Bar<> class before '////'. Thanks a lot for any input, Michal

      G Offline
      G Offline
      Giorgi Dalakishvili
      wrote on last edited by
      #2

      You will have to use reflection I guess

      #region signature my articles #endregion

      1 Reply Last reply
      0
      • M michal kreslik

        Hello, I can't figure this one out, so I'll be happy if someone lends me a helping hand here. How do I instantiate an object with a generic type parameter if I don't know what the type parameter will be at run time? Example:

        namespace GenericTypeInitialization
        {
        class Program
        {
        static void Main()
        {
        Console.WriteLine("Press 1 for FooA, press 2 for FooB:");
        ConsoleKeyInfo key = Console.ReadKey(true);

                Type TypeOfFoo;
        
                if (key.KeyChar == '1')
                {
                    Console.WriteLine("FooA selected.");
                    TypeOfFoo = typeof(FooA);
                }
                else if (key.KeyChar == '2')
                {
                    Console.WriteLine("FooB selected.");
                    TypeOfFoo = typeof(FooB);
                }
        
                ////
                Bar<TypeOfFoo> MyInstanceOfBar = new Bar<TypeOfFoo>();
            }
        }
        
        class FooA {}
        
        class FooB {}
        
        class Bar<TFoo> {}
        

        }

        Obviously, the above code doesn't compile. I'm getting an error of The type or namespace name 'TypeOfFoo' could not be found (are you missing a using directive or an assembly reference?) How do I get the type parameter at run time then? I've tried various things, but none worked. Also, you can't instantiate the Bar<> class before '////'. Thanks a lot for any input, Michal

        E Offline
        E Offline
        Ennis Ray Lynch Jr
        wrote on last edited by
        #3

        You can't. Generics in .NET are evaluated during runtime creating special types, [^] The best solution to your problem is to use inheritance and base classes.

        Need a C# Consultant? I'm available.
        Happiness in intelligent people is the rarest thing I know. -- Ernest Hemingway

        1 Reply Last reply
        0
        • M michal kreslik

          Hello, I can't figure this one out, so I'll be happy if someone lends me a helping hand here. How do I instantiate an object with a generic type parameter if I don't know what the type parameter will be at run time? Example:

          namespace GenericTypeInitialization
          {
          class Program
          {
          static void Main()
          {
          Console.WriteLine("Press 1 for FooA, press 2 for FooB:");
          ConsoleKeyInfo key = Console.ReadKey(true);

                  Type TypeOfFoo;
          
                  if (key.KeyChar == '1')
                  {
                      Console.WriteLine("FooA selected.");
                      TypeOfFoo = typeof(FooA);
                  }
                  else if (key.KeyChar == '2')
                  {
                      Console.WriteLine("FooB selected.");
                      TypeOfFoo = typeof(FooB);
                  }
          
                  ////
                  Bar<TypeOfFoo> MyInstanceOfBar = new Bar<TypeOfFoo>();
              }
          }
          
          class FooA {}
          
          class FooB {}
          
          class Bar<TFoo> {}
          

          }

          Obviously, the above code doesn't compile. I'm getting an error of The type or namespace name 'TypeOfFoo' could not be found (are you missing a using directive or an assembly reference?) How do I get the type parameter at run time then? I've tried various things, but none worked. Also, you can't instantiate the Bar<> class before '////'. Thanks a lot for any input, Michal

          L Offline
          L Offline
          Le centriste
          wrote on last edited by
          #4

          Generics are designed to be used when you know the type at compile-time (early binding). When you don't know the type until run-time (late binding), you have to use reflection.

          ----- You seem eager to impose your preference of preventing others from imposing their preferences on others. -- Red Stateler, Master of Circular Reasoning and other fallacies If atheism is a religion, then not collecting stamps is a hobby. -- Unknown God is the only being who, to rule, does not need to exist. -- Charles Baudelaire

          M 1 Reply Last reply
          0
          • L Le centriste

            Generics are designed to be used when you know the type at compile-time (early binding). When you don't know the type until run-time (late binding), you have to use reflection.

            ----- You seem eager to impose your preference of preventing others from imposing their preferences on others. -- Red Stateler, Master of Circular Reasoning and other fallacies If atheism is a religion, then not collecting stamps is a hobby. -- Unknown God is the only being who, to rule, does not need to exist. -- Charles Baudelaire

            M Offline
            M Offline
            michal kreslik
            wrote on last edited by
            #5

            Ok, so how would you use reflection to make the above example work as intended? Thanks, Michal

            L 1 Reply Last reply
            0
            • M michal kreslik

              Ok, so how would you use reflection to make the above example work as intended? Thanks, Michal

              L Offline
              L Offline
              Le centriste
              wrote on last edited by
              #6

              I reexamined your example, and her is what I suggest. Since you only have 2 well-known concrete classes, you may not need reflection for now, but generics is not the way to go either. Make an interface:

              public interface IFoo
              {
                  void MyMethod(); // Interface defines one method.
              }
              

              Then have some implementation, 2 in you example:

              public class FooA : IFoo
              {
                  public void MyMethod() { Console.WriteLine("Hello from FooA"); }
              }
              
              public class FooB : IFoo
              {
                  public void MyMethod() { Console.WriteLine("Hello from FooB"); }
              }
              

              Then, using your example code:

              class Program
              {
                  static void Main()
                  {
                      Console.WriteLine("Press 1 for FooA, press 2 for FooB:");
                      ConsoleKeyInfo key = Console.ReadKey(true);            
                      IFoo myFoo = null;            
              
                      if (key.KeyChar == '1')            
                      {                
                          myFoo = new FooA();            
                      }            
                      else if (key.KeyChar == '2')            
                      {                
                          myFoo = new FooB();            
                      }
                      else
                      {
                          throw new InvalidOperationException("Wrong selection, you must select 1 or 2"); // Always have a watch dog.
                      }
              
                      myFoo.MyMethod(); // This prints which foo was created.
                  }
              }
              

              This example is pretty simplistic, but you get the idea. In this particular case, you didn't need generics nor reflection. In real-life application, this is rarely sufficient. Read on reflection, I am sure there are quite good articles on this site. Good luck.

              ----- You seem eager to impose your preference of preventing others from imposing their preferences on others. -- Red Stateler, Master of Circular Reasoning and other fallacies If atheism is a religion, then not collecting stamps is a hobby. -- Unknown God is the only being who, to rule, does not need to exist. -- Charles Baudelaire

              M 1 Reply Last reply
              0
              • L Le centriste

                I reexamined your example, and her is what I suggest. Since you only have 2 well-known concrete classes, you may not need reflection for now, but generics is not the way to go either. Make an interface:

                public interface IFoo
                {
                    void MyMethod(); // Interface defines one method.
                }
                

                Then have some implementation, 2 in you example:

                public class FooA : IFoo
                {
                    public void MyMethod() { Console.WriteLine("Hello from FooA"); }
                }
                
                public class FooB : IFoo
                {
                    public void MyMethod() { Console.WriteLine("Hello from FooB"); }
                }
                

                Then, using your example code:

                class Program
                {
                    static void Main()
                    {
                        Console.WriteLine("Press 1 for FooA, press 2 for FooB:");
                        ConsoleKeyInfo key = Console.ReadKey(true);            
                        IFoo myFoo = null;            
                
                        if (key.KeyChar == '1')            
                        {                
                            myFoo = new FooA();            
                        }            
                        else if (key.KeyChar == '2')            
                        {                
                            myFoo = new FooB();            
                        }
                        else
                        {
                            throw new InvalidOperationException("Wrong selection, you must select 1 or 2"); // Always have a watch dog.
                        }
                
                        myFoo.MyMethod(); // This prints which foo was created.
                    }
                }
                

                This example is pretty simplistic, but you get the idea. In this particular case, you didn't need generics nor reflection. In real-life application, this is rarely sufficient. Read on reflection, I am sure there are quite good articles on this site. Good luck.

                ----- You seem eager to impose your preference of preventing others from imposing their preferences on others. -- Red Stateler, Master of Circular Reasoning and other fallacies If atheism is a religion, then not collecting stamps is a hobby. -- Unknown God is the only being who, to rule, does not need to exist. -- Charles Baudelaire

                M Offline
                M Offline
                michal kreslik
                wrote on last edited by
                #7

                Hello, thanks for your reply. Unfortunately, this is not what I need. Interface was my first thought on how to solve this, but I can't use the interface because I have to be able to copy the containing type by value, not by reference. If you declare the object as an interface, you can only copy it as a reference later on (unless you unbox it in which case you - again - need to know its type :) I did not include the error handling in my example as I guess we are solving something else here. Also, as I said, the type should not be instantiated before '////' mark. It's actually being instantiated much later on in the code, but I need to know the type first. I've been working with reflection and generics before. My above example is a much simplified illustration of what I need to do, but the main issue is still finding out the type and passing it along as a parameter. Thanks, Michal

                1 Reply Last reply
                0
                • M michal kreslik

                  Hello, I can't figure this one out, so I'll be happy if someone lends me a helping hand here. How do I instantiate an object with a generic type parameter if I don't know what the type parameter will be at run time? Example:

                  namespace GenericTypeInitialization
                  {
                  class Program
                  {
                  static void Main()
                  {
                  Console.WriteLine("Press 1 for FooA, press 2 for FooB:");
                  ConsoleKeyInfo key = Console.ReadKey(true);

                          Type TypeOfFoo;
                  
                          if (key.KeyChar == '1')
                          {
                              Console.WriteLine("FooA selected.");
                              TypeOfFoo = typeof(FooA);
                          }
                          else if (key.KeyChar == '2')
                          {
                              Console.WriteLine("FooB selected.");
                              TypeOfFoo = typeof(FooB);
                          }
                  
                          ////
                          Bar<TypeOfFoo> MyInstanceOfBar = new Bar<TypeOfFoo>();
                      }
                  }
                  
                  class FooA {}
                  
                  class FooB {}
                  
                  class Bar<TFoo> {}
                  

                  }

                  Obviously, the above code doesn't compile. I'm getting an error of The type or namespace name 'TypeOfFoo' could not be found (are you missing a using directive or an assembly reference?) How do I get the type parameter at run time then? I've tried various things, but none worked. Also, you can't instantiate the Bar<> class before '////'. Thanks a lot for any input, Michal

                  D Offline
                  D Offline
                  darkelv
                  wrote on last edited by
                  #8
                  class Program
                      {
                          static void Main(string[] args)
                          {
                              Console.WriteLine((new Bar<FooA>()).ToString());
                              Console.WriteLine((new Bar<FooB>()).ToString());
                          }
                      }
                  
                      public abstract class BaseFoo
                      {
                      }
                  
                      public class FooA: BaseFoo
                      {
                          public FooA()
                          {
                          }
                          public override string ToString()
                          {
                              return "FooA";
                          }
                      }
                  
                      public class FooB: BaseFoo
                      {
                          public FooB()
                          {
                          }
                          public override string ToString()
                          {
                              return "FooB";
                          }
                      }
                  
                      public class Bar<TFoo> where TFoo : BaseFoo, new()
                      {
                          TFoo tFoo = new TFoo();
                          public override string ToString()
                          {
                              return tFoo.ToString();
                          }
                      }
                  
                  M 1 Reply Last reply
                  0
                  • M michal kreslik

                    Hello, I can't figure this one out, so I'll be happy if someone lends me a helping hand here. How do I instantiate an object with a generic type parameter if I don't know what the type parameter will be at run time? Example:

                    namespace GenericTypeInitialization
                    {
                    class Program
                    {
                    static void Main()
                    {
                    Console.WriteLine("Press 1 for FooA, press 2 for FooB:");
                    ConsoleKeyInfo key = Console.ReadKey(true);

                            Type TypeOfFoo;
                    
                            if (key.KeyChar == '1')
                            {
                                Console.WriteLine("FooA selected.");
                                TypeOfFoo = typeof(FooA);
                            }
                            else if (key.KeyChar == '2')
                            {
                                Console.WriteLine("FooB selected.");
                                TypeOfFoo = typeof(FooB);
                            }
                    
                            ////
                            Bar<TypeOfFoo> MyInstanceOfBar = new Bar<TypeOfFoo>();
                        }
                    }
                    
                    class FooA {}
                    
                    class FooB {}
                    
                    class Bar<TFoo> {}
                    

                    }

                    Obviously, the above code doesn't compile. I'm getting an error of The type or namespace name 'TypeOfFoo' could not be found (are you missing a using directive or an assembly reference?) How do I get the type parameter at run time then? I've tried various things, but none worked. Also, you can't instantiate the Bar<> class before '////'. Thanks a lot for any input, Michal

                    M Offline
                    M Offline
                    Mark Churchill
                    wrote on last edited by
                    #9

                    You'll be looking at TypeBuilder.MakeGenericType unfortunately I think...

                    Mark Churchill Director Dunn & Churchill Free Download:
                    Diamond Binding: The simple, powerful, reliable, and effective data layer toolkit for Visual Studio.

                    M 1 Reply Last reply
                    0
                    • D darkelv
                      class Program
                          {
                              static void Main(string[] args)
                              {
                                  Console.WriteLine((new Bar<FooA>()).ToString());
                                  Console.WriteLine((new Bar<FooB>()).ToString());
                              }
                          }
                      
                          public abstract class BaseFoo
                          {
                          }
                      
                          public class FooA: BaseFoo
                          {
                              public FooA()
                              {
                              }
                              public override string ToString()
                              {
                                  return "FooA";
                              }
                          }
                      
                          public class FooB: BaseFoo
                          {
                              public FooB()
                              {
                              }
                              public override string ToString()
                              {
                                  return "FooB";
                              }
                          }
                      
                          public class Bar<TFoo> where TFoo : BaseFoo, new()
                          {
                              TFoo tFoo = new TFoo();
                              public override string ToString()
                              {
                                  return tFoo.ToString();
                              }
                          }
                      
                      M Offline
                      M Offline
                      michal kreslik
                      wrote on last edited by
                      #10

                      Thanks for your post, but it doesn't solve the problem of instantiating the class with a generic parameter on demand during run time. Also, the generic object can't inherit the abstract class because as I said, it has to be copiable by value, not by reference. Michal

                      1 Reply Last reply
                      0
                      • M Mark Churchill

                        You'll be looking at TypeBuilder.MakeGenericType unfortunately I think...

                        Mark Churchill Director Dunn & Churchill Free Download:
                        Diamond Binding: The simple, powerful, reliable, and effective data layer toolkit for Visual Studio.

                        M Offline
                        M Offline
                        michal kreslik
                        wrote on last edited by
                        #11

                        Hello, Mark, thanks, I've looked into TypeBuilder, but this class is used to build the objects on the fly. I don't need to BUILD the obect on the fly, I already have the objects well defined beforehand. I just need a reference for that object type. So it looks like this cannot be accomplished in C#.

                        M 1 Reply Last reply
                        0
                        • M michal kreslik

                          Hello, Mark, thanks, I've looked into TypeBuilder, but this class is used to build the objects on the fly. I don't need to BUILD the obect on the fly, I already have the objects well defined beforehand. I just need a reference for that object type. So it looks like this cannot be accomplished in C#.

                          M Offline
                          M Offline
                          Mark Churchill
                          wrote on last edited by
                          #12

                          You could have an IDictionary and preinitialize it with {typeof(Foo), typeof(Bar< Foo >)}, {typeof(Deh), typeof(Bar< Deh >)...}

                          Mark Churchill Director Dunn & Churchill Free Download:
                          Diamond Binding: The simple, powerful, reliable, and effective data layer toolkit for Visual Studio.

                          modified on Thursday, February 07, 2008 6:13:04 AM

                          1 Reply Last reply
                          0
                          Reply
                          • Reply as topic
                          Log in to reply
                          • Oldest to Newest
                          • Newest to Oldest
                          • Most Votes


                          • Login

                          • Don't have an account? Register

                          • Login or register to search.
                          • First post
                            Last post
                          0
                          • Categories
                          • Recent
                          • Tags
                          • Popular
                          • World
                          • Users
                          • Groups