Why can't I implement an interface method that returns an interface with a method that returns a concrete type?
E.g.:
public interface J
{
}
public interface I
{
public J M();
}
public class D : J
{
}
public class C : I
{
public D M()
{
return new D();
}
}
gives
Method 'M' cannot implement method from interface '.I'. Return type should be 'J'.
because the compiler wants me to change the return type of C.M
to J
, which I don't want.
CodePudding user response:
Interfaces do not allow you to use a different return type for a defined method, even if the return type inherits from the one defined within the interface.
You can however circumvent this by using Explicit Interface Implementations. The main purpose of these implementations is if you want to create a class that inherits from multiple interfaces that have different definitions of the same method, but it can also potentially be used effectively in this situation.
However, I would be very careful when implementing this. If you don't implement it well, this has the potential to cause a lot of headache and confusion since it is effectively overriding what a class is normally forced to do when implementing an interface.
Here's an example of this:
public class DataClass1
{
}
public class DataClass2 : DataClass1
{
}
interface IDataInterface
{
public DataClass1 GetData();
}
class DataProvider : IDataInterface
{
public DataClass2 GetData()
{
return new DataClass2();
}
DataClass1 IDataInterface.GetData() => GetData();
}
class Program
{
public static void Main()
{
var provider = new DataProvider();
var providerInterface = (IDataInterface)provider;
provider.GetData(); // Returns DataClass2
providerInterface.GetData(); // Returns DataClass1
}
}
CodePudding user response:
The whole point of implementing an interface is to conform to Liskov Substitution Principle (on compile-time level). It says that every implementation of an interface is as good as any other. It gives you freedom to easily swap this implementation for another one, without having to readjust all calls.
What you're trying to do is to make this particular implementation different than others. You want a situation when your code (which knows it's dealing with this particular implementation of the interface) to instantly recognize that the returned value is of some other particular implementation.
That's way outside of the scope of your interfaces here. For out-of-interface calls use out-of interface names. Otherwise, you're breaking the very reason to have interface.