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();
}
}