[英]Interface implementation confusion
假設你有這個:
// 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只顯示我和簡單的常用方法,我想在其中顯示更具體的接口。
我怎么能做到這一點? 這段代碼有什么問題?
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);
}
}
正如評論所指出的那樣,您可以在顯式實現中調用更具體的版本。
你可以用作:
IMyCrazyDataResult result = new MyCrazySerializer().Serialize<int>(1);
ISerializer serializer = (ISerializer)new MyCrazySerializer();
IDataResult = serializer.Serialize<int>(1);
您可以在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
。
為什么在這個世界上我得到這個編譯錯誤? 我尊重界面
不,你不是。 您沒有返回IDataResult
,而是返回IMyCrazyDataResult
。 是的,它從inherites 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
}
}
與C ++不同,C#沒有協變返回類型 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.