![](/img/trans.png)
[英]Generic interface implementation: Generic return type and generic input type
[英]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
的實例,因此無法嘗試將MenuSettings
為IInitializerSettings<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.