简体   繁体   中英

Implement a generic interface missing new constraint

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?

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".

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM