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 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