Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 接口实现混乱_C#_Oop_Interface - Fatal编程技术网

C# 接口实现混乱

C# 接口实现混乱,c#,oop,interface,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 : IDataResul

假设您有:

// 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();
    }
}
//通用
公共接口ISerializer
{
IDataResult序列化(T实例);
}
//通用
公共接口IDataResult
{
}
//具体-我实现IDataResult
公共接口IMyCrazyDataResult:IDataResult
{
}
公共类MyCrazySerializer:ISerializer
{
//编译错误:
//错误CS0738:“MyCrazySerializer”未实现接口成员“ISerializer.Serialize(T)”。
//“MyCrazySerializer.Serialize(T)”无法实现“ISerializer.Serialize(T)”,因为它实现了
//没有匹配的返回类型“IDataResult”。
公共IMyCrazyDataResult序列化(T实例)
{
抛出新的NotImplementedException();
}
}
我到底为什么会出现这种编译错误?我尊重接口——事实上,我确实返回了一个IDataResult,尽管是间接的。是编译器无法理解这一点,还是有什么根本性的错误(在面向对象的层次上)

我认为拥有一个接口的全部意义在于我可以保证一些实现,但让它为我提供附加功能。这就是我正在做的——但是我得到了一个编译错误

在我的实际代码中,我希望返回类型更具体一点,因为我在派生接口中有几个额外的方法。如果我将MyCrazySerializer.Serialize的返回类型设置为IDataResult类型,那么intellisense只会显示我和基本的通用方法,我想在其中显示更具体的接口

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

我到底为什么会出现这种编译错误?我尊重界面

不,你不是。您返回的不是
IDataResult
,而是
IMyCrazyDataResult
。是的,它继承自
IDataResult
,但与之不同


当涉及到接口时,您不会得到差异-类型必须完全匹配。

您没有充分履行接口契约,因为您指定了不同的内容作为方法的返回类型,签名必须完全匹配。这并不意味着您不能返回更为指定的接口,以下情况非常好:

// 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
{
    public IDataResult Serialize<T>(T instance)
    {
        // return a IMyCrazyDataResult here
    }
}
//通用
公共接口ISerializer
{
IDataResult序列化(T实例);
}
//通用
公共接口IDataResult
{
}
//具体-我实现IDataResult
公共接口IMyCrazyDataResult:IDataResult
{
}
公共类MyCrazySerializer:ISerializer
{
公共IDataResult序列化(T实例)
{
//在此处返回IMyCrazyDataResult
}
}
>P>不同于C++,C没有。

C不支持,所以您需要像接口上出现的那样实现<代码>序列化< /C> >方法。但是,您可以显式地实现它,这意味着任何知道MyCrazySerializer真正类型的客户端都可以访问更具体的方法:

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

    IDataResult ISerializer.Serialize<T>(T instance)
    {
        return this.Serialize(instance);
    }
}
公共类MyCrazySerializer:ISerializer
{
公共IMyCrazyDataResult序列化(T实例)
{
抛出新的NotImplementedException();
}
IDataResult ISerializer.Serialize(T实例)
{
返回此.Serialize(实例);
}
}
正如注释所指出的,您可以在显式实现中调用更具体的版本

您可以将其用作:

IMyCrazyDataResult result = new MyCrazySerializer().Serialize<int>(1);
ISerializer serializer = (ISerializer)new MyCrazySerializer();
IDataResult = serializer.Serialize<int>(1);
IMyCrazyDataResult=new MyCrazySerializer().Serialize(1);
ISerializer序列化程序=(ISerializer)新MyCrazySerializer();
IDataResult=serializer.Serialize(1);

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

//通用
公共接口ISerializer,其中TResult:IDataResult
{
TResult序列化(T实例);
}
//通用
公共接口IDataResult
{
}
//具体-我实现IDataResult
公共接口IMyCrazyDataResult:IDataResult
{
}
公共类MyCrazySerializer:ISerializer
{
公共IMyCrazyDataResult序列化(T实例)
{
抛出新的NotImplementedException();
}
}

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

可能重复的@euphoric-我同意,关于另一个帖子有很多好的信息。我认为OP已经展示了足够的能力,为什么他希望它能工作?为什么它需要精确匹配,而不尊重派生类型?为什么实现如此脆弱?为什么不允许OO原则?为什么不允许派生类型-这是OO的核心!!?!?请参见(C#编译器团队的一名开发人员)关于该主题的内容。为什么?与派生类型相比,精确类型的意义何在?这似乎是一个脆弱的想法。@RobertSeder-这就是语言设计者决定设计语言的方式。我没有想到这一点!这确实给了我想要的东西。我做ISerialier s=新的MyCrazySerializer().Seri。。。intellisense首先显示我的自定义界面,但通过强制转换,我也可以看到IDataResult。。。谢谢如果编写显式版本来调用另一个版本:
IDataResult ISerializer.Serialize(T instance{return Serialize(instance);}
如果您无法修改
ISerializer
接口,这当然是一种方法。我似乎不需要这样做,但这会起作用。理想情况下,我希望我的接口更干净一点。
// 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();
    }
}