Implement a common interface that does not require new restrictions

Consider the following interface:

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

Trying to implement this with

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

does not work, the compiler complains that in M no restriction new() .

When I add a restriction, as in

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

this still does not do the trick, since the restrictions of Foo.Bar now do not comply with the restrictions of the interface method (and I cannot change them).

Documentation for compiler error CS0425 reports

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 to do it?

+5
source share
3 answers

If you cannot change the definition of an interface, you should not use new M(); - instead of Activator.CreateInstance :

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

Of course, you may encounter a run-time error if there is no constructor without parameters for M , but this is inevitable (again, because we cannot change the general constraints).


Re: documentation:

implement the interface explicitly.

I think they are trying to get here, "if you have a base class method that has one set of common restrictions, and you want to implement an interface that has a different set of restrictions for a method with the same name, an explicit implementation is one way of doing this binding. "

+6
source

Implementing an interface is clearly not a solution. The compiler just tells you that if you need a common Bar method with this restriction, then I’ll explicitly implement the interface so that both versions of Bar can coexist, but this is obviously not the solution you are looking for.

The only solutions are:

  • Implement a generic type constraint in an interface.
  • Create a new M through reflection: Activator.CreateInstance and pay the price of security loss during compilation; nothing forces M have a constructor without parameters.
+5
source

You can create an explicit implementation of an interface by right-clicking on an interface in a class that must implement it and select "implement explicitly." Method names must be crossed out with the interface name.

0
source

Source: https://habr.com/ru/post/1264241/


All Articles