假设你有这个:
// 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();
}
}
为什么我在世界上遇到这个编译错误?我尊重界面 - 事实上,我确实返回了IDataResult,尽管是间接的。难道编译器无法解决这个问题,或者是否存在根本(在OO级别)错误的问题,在这里?
我认为拥有接口的全部意义在于我可以保证一些实现,但是让它为我添加它。这就是我正在做的 - 但我得到一个编译错误。
在我的实际代码中,我希望返回类型更具体,因为我在派生接口中有几个额外的方法。如果我做了类型IDataResult的MyCrazySerializer.Serialize的返回类型,那么intellisense只显示我和简单的常用方法,我想要显示更具体的界面。
我怎么能做到这一点?这段代码有什么问题???
答案 0 :(得分:5)
C#不支持return type covariance,因此您需要完全按照界面上显示的方式实施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);
}
}
正如评论所指出的那样,您只需在显式实现中调用更具体的版本。
您可以将其用作:
IMyCrazyDataResult result = new MyCrazySerializer().Serialize<int>(1);
ISerializer serializer = (ISerializer)new MyCrazySerializer();
IDataResult = serializer.Serialize<int>(1);
答案 1 :(得分: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();
}
}
明确声明Serialize
的返回类型来自IDataResult
,而不是TResult
。
答案 2 :(得分:3)
为什么我在世界上遇到这个编译错误?我尊重界面
不,你不是。您没有返回IDataResult
,而是IMyCrazyDataResult
。是的,它继承自IDataResult
,但与不相同。
说到接口,你不会得到差异 - 类型必须完全匹配。
答案 3 :(得分:3)
您没有充分了解接口合约,因为您指定了不同的方法作为方法的返回类型,签名必须完全匹配。这并不意味着你不能返回更多指定的接口,以下是完全正常的:
// 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
}
}
答案 4 :(得分:1)
与C ++不同,C#没有covariant return type。