views:

97

answers:

3

Hi,

Is there a way to create a Generic Method that uses the new() Constraint and only accepts constructors of a given type?

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.");
    }
    // ...
}

Is it possible to have something like this instead?

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

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
I wanted to see if I could remove the constructor validation I have, and I won't be able to do it with this but it could be really useful on the future. Thanks!
Joel Ferreras
+1  A: 

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
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...
Joel Ferreras
@Joel: The option they show is the ONLY option for the new() constraint. THere's no way to add parameters.
Reed Copsey
+1  A: 

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
It would be a nice addition though!
Joel Ferreras