59

I have a Generic Type Interface and want a constructor of an object to take in the Generic Interface.
Like:

public Constructor(int blah, IGenericType<T> instance)
{}

I want the code that creates this object to specify the IGenericType (use Inversion of Control). I have not seen a way for this to happen. Any suggestions to accomplish this?

I want someone to create the object like:

Constructor varname = new Constructor(1, new GenericType<int>());
Svante
  • 50,694
  • 11
  • 78
  • 122
CSharpAtl
  • 7,374
  • 8
  • 39
  • 53

1 Answers1

73

You can't make constructors generic, but you can use a generic static method instead:

public static Constructor CreateInstance<T>(int blah, IGenericType<T> instance)

and then do whatever you need to after the constructor, if required. Another alternative in some cases might be to introduce a non-generic interface which the generic interface extends.

EDIT: As per the comments...

If you want to save the argument into the newly created object, and you want to do so in a strongly typed way, then the type must be generic as well.

At that point the constructor problem goes away, but you may want to keep a static generic method anyway in a non-generic type: so you can take advantage of type inference:

public static class Foo
{
    public static Foo<T> CreateInstance<T>(IGenericType<T> instance)
    {
        return new Foo<T>(instance);
    }
}

public class Foo<T>
{
    public Foo(IGenericType<T> instance)
    {
        // Whatever
    }
}

...

IGenericType<string> x = new GenericType<string>();
Foo<string> noInference = new Foo<string>(x);
Foo<string> withInference = Foo.CreateInstance(x);
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • I would like to save the IGenericType as a member var, to do that I guess I would have to make the whole class generic not just the method...? – CSharpAtl Mar 31 '09 at 13:48
  • 1
    Yes, if you need it to be strongly typed as a member variable, then you should make the whole type generic and then the constructor problem goes away. – Jon Skeet Mar 31 '09 at 13:52
  • would like to run my design idea by you to see if there is something fundamentally better to do. Dont think I can type it all in this comment. Can I post to your blog or email you? – CSharpAtl Mar 31 '09 at 13:55
  • 3
    Unfortunately, generic static methods don't allow to use object initializers. This fails to compile: Foo.CreateInstance(x) { Prop = "42" }; – Bruno Martinez May 11 '11 at 21:45
  • @Bruno: Indeed... that's definitely unfortunate :( – Jon Skeet May 11 '11 at 22:15
  • @JonSkeet What is this IGenericType you guys are talking about? I am running a old version of .net and it is not included (i think)? – jordan Nov 01 '13 at 21:48
  • @jordan.peoples: It's not any specific type - it's just an example of a generic interface, with a concrete implementation of `GenericType`. – Jon Skeet Nov 01 '13 at 22:19
  • "You can't make constructors generic" - But why not(?) - Is the real question here... does this mean that every Form which depends on Generics as parameters needs t be static O_o?! – solujic Feb 07 '17 at 10:09
  • @ChenChi: I'm afraid I don't understand your comment at all, or whether it's specific to forms. I suggest you ask a more detailed new question. – Jon Skeet Feb 07 '17 at 12:21
  • @JonSkeet: Yea it's specific to forms... I was trying to make a "DataGridView Form" which has IEnumerable dataSource as a parameter in constructor...sry for almost off-topic comment but I don't quite understand your solution in the context of Form constructors – solujic Feb 07 '17 at 14:52
  • @JonSkeet I wrote about my problem here: http://softwareengineering.stackexchange.com/questions/341432/how-should-i-implement-generic-datagrid-for-crud-operations – solujic Feb 07 '17 at 14:58
  • @ChenChi: That doesn't look like a very specific question at the moment... (And a DataGrid isn't a Form...) – Jon Skeet Feb 07 '17 at 15:00
  • @Jon Skeet: well I know that DataGrid isn't a form, but if I used a Form specifically for DataGridView I call it "DataGridView Form"... to make it more specific my problem was making a constructor which has Generic type as a parameter in my case "IEnumerable dataSource" – solujic Feb 07 '17 at 15:02
  • @ChenChi: Sorry, but comment threads really aren't meant to be for discussion like this. Please ask a much more specific question here on SO. – Jon Skeet Feb 07 '17 at 15:12
  • The static function requires the generic type on the name too: **public static Foo CreateInstance(IGenericType instance){...}** – Adam LaStrange Dec 22 '17 at 17:43