接口实现混乱

Rob*_*der 4 c# oop interface

假设你有这个:

// General purpose
public interface ISerializer
{
    IDataResult Serialize<T>(T instance);
}

// General purpose
public interface IDataResult
{
}

// Specific - and I implement IDataResult
public interface IMyCrazyDataResult : IDataResult
{
}

public class MyCrazySerializer : ISerializer
{
    // COMPILE ERROR:
    // error CS0738: 'MyCrazySerializer' does not implement interface member 'ISerializer.Serialize<T>(T)'. 
    // 'MyCrazySerializer.Serialize<T>(T)' cannot implement 'ISerializer.Serialize<T>(T)' because it does 
    // not have the matching return type of 'IDataResult'.
    public IMyCrazyDataResult Serialize<T>(T instance)
    {
        throw new NotImplementedException();
    }
}
Run Code Online (Sandbox Code Playgroud)

为什么在这个世界上我得到这个编译错误?我尊重界面 - 事实上,我确实返回了IDataResult,尽管是间接的.是编译器无法解决这个问题还是从根本上(在OO级别)出现了错误的问题,在这里?

我认为拥有一个接口的全部意义在于我可以保证一些实现,但是让它为我添加它.这就是我正在做的 - 但我得到一个编译错误.

在我的实际代码中,我希望返回类型更具体,因为我在派生接口中有几个额外的方法.如果我创建类型为IDataResult的MyCrazySerializer.Serialize的返回类型,那么intellisense只显示我和简单的常用方法,我想在其中显示更具体的接口.

我怎么能做到这一点?这段代码有什么问题?

Lee*_*Lee 5

C#不支持返回类型协方差,因此您需要Serialize<T>完全按照界面上显示的方法实现该方法.您可以明确地实现它,这意味着任何知道真实类型的客户端都MyCrazySerializer可以访问更具体的方法:

public class MyCrazySerializer : ISerializer
{
    public IMyCrazyDataResult Serialize<T>(T instance)
    {
        throw new NotImplementedException();
    }

    IDataResult ISerializer.Serialize<T>(T instance)
    {
        return this.Serialize(instance);
    }
}
Run Code Online (Sandbox Code Playgroud)

正如评论所指出的那样,您可以在显式实现中调用更具体的版本.

你可以用作:

IMyCrazyDataResult result = new MyCrazySerializer().Serialize<int>(1);
ISerializer serializer = (ISerializer)new MyCrazySerializer();
IDataResult = serializer.Serialize<int>(1);
Run Code Online (Sandbox Code Playgroud)


Dan*_*ker 5

您可以在C#中构建自己的返回类型协方差:

// General purpose
public interface ISerializer<out TResult> where TResult : IDataResult
{
    TResult Serialize<T>(T instance);
}

// General purpose
public interface IDataResult
{
}

// Specific - and I implement IDataResult
public interface IMyCrazyDataResult : IDataResult
{
}

public class MyCrazySerializer : ISerializer<IMyCrazyDataResult>
{
    public IMyCrazyDataResult Serialize<T>(T instance)
    {
        throw new NotImplementedException();
    }
}
Run Code Online (Sandbox Code Playgroud)

Serialize明确声明返回类型是源自IDataResult而不是精确的TResult.