簡體   English   中英

返回具有不同泛型類型的泛型接口實現

[英]Return generic interface implementation with different generic type

我創建了這個簡單的通用接口:

public interface IInitializerSettings<in ViewerType> where ViewerType : Component
{
    void Apply(ViewerType dataViewer);
}

並為其添加了一個實現:

public class MenuSettings : IInitializerSettings<CustomGridLayout>
{
    public void Apply(CustomGridLayout dataViewer)
    {
        Debug.Log("Applied");
    }
}

public class CustomGridLayout : CustomLayout
{
    // The implementation code
}

現在我嘗試這樣使用它:

public IInitializerSettings<CustomLayout> GetDefaultSettings()
{
    return new MenuSettings();
}

但我收到此錯誤“無法將類型 MenuSettings 轉換為返回類型 IInitializerSettings”

我不明白為什么不允許, CustomGridLayout繼承CustomLayout

我能找到的只是這個問題,但這個解決方案對我不起作用(我不能使用out關鍵字)。

您不能這樣做的原因是,對於逆變接口(通過使用in為泛型類型參數指定),您無法將其隱式轉換為派生程度較低的類型的實例。 如果您從IEnumerable<T> (協變)和Action<T> (逆變)的角度考慮,我認為文檔中的要點解釋得相當好。

正如 Selvin 在評論中提到的那樣, MenuSettings中的Apply方法需要一個CustomGridLayout的實例,因此無法嘗試將MenuSettingsIInitializerSettings<CustomLayout> ,因為public void Apply(CustomGridLayout dataViewer)無法將CustomLayout作為輸入處理。 讓我舉個例子:

public class CustomLayout
{
    public void SetupCustomLayout() { ... }
}

public class CustomGridLayout : CustomLayout
{
    public void SetupGrid() { ... }
}

public class MenuSettings : IInitializerSettings<CustomGridLayout>
{
    public void Apply(CustomGridLayout dataViewer)
    {
        dataViewer.SetupGrid();
    }
}


// Later in the code...

var menuSettings = new MenuSettings();

// This cast is what GetDefaultSettings() is trying to do
var genericSettings = (IInitializerSettings<CustomLayout>)menuSettings;

var layout = new CustomLayout();

// Looking at the type of 'genericSettings' this following line should be possible
// but 'MenuSettings.Apply()' is calling 'dataViewer.SetupGrid()' which doesn't exist
// in 'layout', so 'layout' is not a valid input
genericSettings.Apply(layout);

因此,關於文檔,您已將IInitializerSettings<ViewerType>定義為逆變接口,但正試圖將其用作協變接口 - 這是不可能的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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