25

Is there a way to create a Generic Method that uses the new() constraint to require classes with constructor attributes of specific types?

For Example:

I have the following code:

public T MyGenericMethod<T>(MyClass c) where T : class
{
    if (typeof(T).GetConstructor(new Type[] { typeof(MyClass) }) == null)
    {
        throw new ArgumentException("Invalid class supplied");
    }
    // ...
}

Is it possible to have something like this instead?

public T MyGenericMethod<T>(MyClass c) where T : new(MyClass)
{
    // ...
}

EDIT: There's a suggestion regarding this. Please vote so we can have this feature in C#!

EDIT 2: The site has been taken down. Now the suggestion is on Github. Follow up there!

Meryovi
  • 6,121
  • 5
  • 42
  • 65
  • 1
    I'm a little confused. What exactly are you trying to accomplish. Will the constructor take a parameter of MyClass, or are you limiting T to MyClass? – Justin Niessner Jul 29 '10 at 15:57
  • 1
    User voice has long since gone the way of the dodo, but there is still [an issue for this in the csharplang](https://github.com/dotnet/csharplang/discussions/769) repository. Here's to the next decade! – Jeroen Mostert Aug 04 '22 at 13:04
  • Great! Updated the question with the new URL. Hope this feature is added in the next 10 years, haha. – Meryovi Aug 04 '22 at 13:09

3 Answers3

33

Not really; C# only supports no-args constructor constraints.

The workaround I use for generic arg constructors is to specify the constructor as a delegate:

public T MyGenericMethod<T>(MyClass c, Func<MyClass, T> ctor) {
    // ...
    T newTObj = ctor(c);
    // ...
}

then when calling:

MyClass c = new MyClass();
MyGenericMethod<OtherClass>(c, co => new OtherClass(co));
thecoop
  • 45,220
  • 19
  • 132
  • 189
  • You can even only use `Func ctor` as a delegate and then pass `MyClass` only in that delegate. This way, `MyGenericMethod` can work with different constructors, e.g. when different dependencies are involved. – rklec Mar 27 '23 at 17:27
8

No. Unfortunately, generic constraints only allow you to include:

where T : new()

Which specifies that there is a default, parameterless constructor. There is no way to constrain to a type with a constructor which accepts a specific parameter type.

For details, see Constraints on Type Parameters.

Reed Copsey
  • 554,122
  • 78
  • 1,158
  • 1,373
  • Yeah, I read that article, but it was not very specific about the new() constraint. Thanks anyway, I guess I'll leave my validation right where it is... – Meryovi Jul 29 '10 at 16:10
  • @Joel: The option they show is the ONLY option for the new() constraint. THere's no way to add parameters. – Reed Copsey Jul 29 '10 at 16:27
3

No, it is not possible in C# to constrain the generic type to have a constructor of a specific signature. Only the parameterless constructor is supported by new().

driis
  • 161,458
  • 45
  • 265
  • 341