簡體   English   中英

接口實現混亂

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM