7

Consider the following interface:

public interface IFoo
{
    M Bar<M>();
}

Trying to implement that with

class Foo : IFoo
{
    public M Bar<M>()
    {
        return new M();
    }
}

does not work, the compiler complains the M is missing a new() constraint.

When I add the constraint as in

class Foo : IFoo
{
    public M Bar<M>() where M : new()
    {
        return new M();
    }
}

this still does not do the trick, as the constraints of Foo.Bar do not match the constraints of the interface method now (and I'm not able to change that).

The documentation for the compiler error CS0425 says

To avoid this error, make sure the where clause is identical in both declarations, or implement the interface explicitly.

If "implementing the interface explicitly" is the solution: How do I do it?

1
  • Is this because you need to return a new one or you need to return something when there is nothing else to return? Would default(M) be good enough? It returns the default value for a given generic type, for references this is null. Otherwise you will need either expression trees or reflection to create your instance. Commented Feb 15, 2017 at 11:05

3 Answers 3

8

If you can't change the interface definition, you'll have to avoid using new M(); - use Activator.CreateInstance instead:

class Foo : IFoo
{
    public M Bar<M>()
    {
        return Activator.CreateInstance<M>();
    }
}

Of course, you may now run into a runtime error if there's no parameterless constructor for M, but that's unavoidable (again, because we can't change the generic constraints).


Re: documentation:

implement the interface explicitly.

I think that what they're trying to get at here is "if you've got a base class method that has one set of generic constraints and you want to implement an interface that has a different set of constraints for a method with the same name, explicit implementation is one way out of that bind".

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you for interpreting the documentation: You're probably right. I was in the mode of thinking "the documentation explains what I've done wrong and shows a way out of the plight", which led me on a wrong path.
6

Implementing the interface explicitly is not the solution. The compiler is simply telling you that if you need a generic method Bar with that constraint, then implement the interface explicitly so both versions of Bar can coexist, but that is, obviously, not the solution your are lookig for.

The only solutions are:

  1. Implement the generic type constraint in the interface.
  2. Instantiate the new M via reflection: Activator.CreateInstance and pay the price of losing type safety at compile time; nothing enforces M to have a parameterless constructor.

4 Comments

Nothing is enforcing that M is even a type that you can instantiate, could be an interface.
@AdamHouldsworth Well yes, any non instantiable type is lacking a usable parameterless constructor. I fail to see the difference you are trying to make.
No difference, just pointing out that no parameterless constructor is the least of the issues really - an observation more than anything. Just reminds me why I tend not to make or use interfaces like this.
@AdamHouldsworth ah ok, understood.
0

You can generate explicit interface implementation by right clicking interface in class which should implement it and selecting "implement explicitly". Methods names should be pereceded with interface's name.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.