繁体   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