简体   繁体   English

为什么我不能用返回具体类型的方法实现返回接口的接口方法

[英]Why can't I implement an interface method that returns an interface with a method that returns a concrete type

Why can't I implement an interface method that returns an interface with a method that returns a concrete type?为什么我不能用返回具体类型的方法实现返回接口的接口方法?

Eg:例如:

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 CM to J , which I don't want.因为编译器要我将CM的返回类型更改为J ,这是我不想要的。

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 .但是,您可以使用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
{

}

public interface IDataInterface
{
    public DataClass1 GetData();
}

public 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
    }
}

The whole point of implementing an interface is to conform to Liskov Substitution Principle (on compile-time level).实现接口的全部要点是符合 Liskov 替换原则(在编译时级别)。 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.否则,你就破坏了拥有界面的理由。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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