Generic type with parametherized constructor

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Andrus

    #1

    Generic type with parametherized constructor

    I need to create instance of generic type when generic type does not
    have parameterless constructor.

    I tried code below but got error shown in comment.
    How to fix ?

    Andrus.

    abstract class QueryFactory<TE ntity{
    public string O1;
    public QueryFactory(st ring o1) {
    O1 = o1;
    }
    }

    class CustomerQueryFa ctory : QueryFactory<Cu stomer{
    public CustomerQueryFa ctory(string o1) : base(o1) { }
    }

    class DocumentForm<TE ntity, TQueryFactory>
    where TQueryFactory : QueryFactory<TE ntity{

    public DocumentForm() {
    // Cannot create an instance of the variable type 'TQueryFactory'
    // because it does not have the new() constraint
    var x = new TQueryFactory(" special parameter created in this method");
    }
    }

    class Customer {
    string Id { get; set; }
    string Name { get; set; }
    }

    class Test {

    static void Main() {
    var x = new DocumentForm<Cu stomer, CustomerQueryFa ctory>();
    }
    }



  • Gilles Kohl [MVP]

    #2
    Re: Generic type with parametherized constructor

    On Mon, 21 Apr 2008 01:32:15 +0300, "Andrus" <kobruleht2@hot .ee>
    wrote:
    >I need to create instance of generic type when generic type does not
    >have parameterless constructor.
    >
    >I tried code below but got error shown in comment.
    >How to fix ?
    This article suggests an alternate solution:



    (Search for "Listing 11.31" to locate the spot I'm referring to)

    Regards,
    Gilles.

    Comment

    • Clint

      #3
      Re: Generic type with parametherized constructor

      The underlying problem is "'TQueryFactory ': cannot provide arguments when
      creating an instance of a variable type"

      So....

      Replace:
      var x = new TQueryFactory(" special parameter created in this method");

      With: (btw - I did it in 2005 so couldn't test with 'var')
      TQueryFactory x = (TQueryFactory) typeof(TQueryFa ctory).GetConst ructor(new
      System.Type[] { typeof(string) }).Invoke(new object[] { "special parameter
      created in this method" });


      Hope that is what you are looking for. Apologies if I have it all wrong,
      it's time to go home and I'm outahere...
      If there is a better way, let me know.

      Cheers.

      "Andrus" <kobruleht2@hot .eewrote in message
      news:OTKS6czoIH A.3976@TK2MSFTN GP03.phx.gbl...
      I need to create instance of generic type when generic type does not
      have parameterless constructor.
      >
      I tried code below but got error shown in comment.
      How to fix ?
      >
      Andrus.
      >
      abstract class QueryFactory<TE ntity{
      public string O1;
      public QueryFactory(st ring o1) {
      O1 = o1;
      }
      }
      >
      class CustomerQueryFa ctory : QueryFactory<Cu stomer{
      public CustomerQueryFa ctory(string o1) : base(o1) { }
      }
      >
      class DocumentForm<TE ntity, TQueryFactory>
      where TQueryFactory : QueryFactory<TE ntity{
      >
      public DocumentForm() {
      // Cannot create an instance of the variable type 'TQueryFactory'
      // because it does not have the new() constraint
      var x = new TQueryFactory(" special parameter created in this method");
      }
      }
      >
      class Customer {
      string Id { get; set; }
      string Name { get; set; }
      }
      >
      class Test {
      >
      static void Main() {
      var x = new DocumentForm<Cu stomer, CustomerQueryFa ctory>();
      }
      }
      >
      >
      >

      Comment

      • Andrus

        #4
        Re: Generic type with parametherized constructor

        TQueryFactory x = (TQueryFactory) typeof(TQueryFa ctory).GetConst ructor(new
        System.Type[] { typeof(string) }).Invoke(new object[] { "special parameter
        created in this method" });
        Thay you very much. It works.
        How to invoke TQueryFactory constructor in type-safe way ?
        Is this C# design flaw ?

        Andrus.


        Comment

        • =?ISO-8859-1?Q?Lasse_V=E5gs=E6ther_Karlsen?=

          #5
          Re: Generic type with parametherized constructor

          Andrus wrote:
          >TQueryFactor y x = (TQueryFactory) typeof(TQueryFa ctory).GetConst ructor(new
          >System.Type[] { typeof(string) }).Invoke(new object[] { "special parameter
          >created in this method" });
          >
          Thay you very much. It works.
          How to invoke TQueryFactory constructor in type-safe way ?
          Is this C# design flaw ?
          >
          Andrus.
          >
          >
          Well, you could say that, but then, if a generic container had a
          restriction to only allow generic types that had a constructor that took
          a string parameter, what exactly would you do?

          You could use it with:

          - something that takes the name of an employee as a parameter
          - something that takes the name of a property as a parameter
          - something that takes a filename as a parameter

          The likely common usage you would get out of this would not be very high.

          At least that's my opinion. No doubt people might have scenarios which
          would make sense, but your response is "but I know I will only use this
          and that type", then my response to that would be to create descendants
          of your container that knew about those specifics.

          --
          Lasse Vågsæther Karlsen
          mailto:lasse@vk arlsen.no
          Blogger is a blog publishing tool from Google for easily sharing your thoughts with the world. Blogger makes it simple to post text, photos and video onto your personal or team blog.

          PGP KeyID: 0xBCDEA2E3

          Comment

          • Marc Gravell

            #6
            Re: Generic type with parametherized constructor

            For info, I've got some "Type" extension methods in MiscUtil that
            provide compiled (i.e. faster) access to Func<...delegat es to do
            precisely this...

            They aren't listed on the overview page, but they are there... IIRC, it
            allows you to do things like someType.Ctor(4 , "abc", 12) etc...

            Pobox has been discontinued as a separate service, and all existing customers moved to the Fastmail platform.


            Marc

            Comment

            • Andrus

              #7
              Re: Generic type with parametherized constructor

              For info, I've got some "Type" extension methods in MiscUtil that provide
              compiled (i.e. faster) access to Func<...delegat es to do precisely
              this...
              >
              They aren't listed on the overview page, but they are there... IIRC, it
              allows you to do things like someType.Ctor(4 , "abc", 12) etc...
              >
              http://www.pobox.com/~skeet/csharp/miscutil/
              I tried
              TQueryFactory qm = typeof(TQueryFa ctory).Ctor(Dat aBase, Ko);

              but got compile error

              No overload for method 'Ctor' takes '2' arguments

              Andrus.


              Comment

              • Marc Gravell

                #8
                Re: Generic type with parametherized constructor

                First you need to get the delegate, and ideally stow it somewhere and
                re-use it; I guess I could change the code to cache this internally
                without any real problems...

                Marc

                using System;
                using MiscUtil.Linq.E xtensions;
                interface IFoo
                {
                void Test();
                }

                class Bar : IFoo
                {
                private string message;
                public Bar(string message)
                {
                this.message = message;
                }
                public void Test()
                {
                Console.WriteLi ne(message);
                }
                }

                class Program
                {
                static void Main()
                {
                // perhaps loaded dynamically, etc
                Type type = typeof(Bar);

                // find the ctor that accepts a string, and
                // return the new object as an IFoo (since
                // we might not know about Bar at compile-time
                // in a plugin/factory/IOC/DI model, etc)
                Func<string, IFooctor = type.Ctor<strin g, IFoo>();

                IFoo foo = ctor("Does it work?");
                foo.Test();
                }
                }

                Comment

                • Andrus

                  #9
                  Re: Generic type with parametherized constructor

                  Marc,
                  First you need to get the delegate, and ideally stow it somewhere and
                  re-use it; I guess I could change the code to cache this internally
                  without any real problems...
                  Thank you. It works.
                  I'm wondering where there is no method for single-line constructor call.

                  Andrus.


                  Comment

                  • Marc Gravell

                    #10
                    Re: Generic type with parametherized constructor

                    If the Type arg was a generic type argument, it would be trivial to
                    implement (via a generic cache-class); as it is, I'd need some kind of
                    lookup (Dictionary<Typ e, ...or similar) - that is the only issue...
                    but you could simply take the source code and use it to make your own
                    implementation. ..

                    Marc

                    Comment

                    Working...