返回具有不同泛型类型的泛型接口实现

SagiZiv

我创建了这个简单的通用接口:

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 在评论中提到的,该Apply方法MenuSettings需要一个 的实例CustomGridLayout,因此尝试强制MenuSettings转换IInitializerSettings<CustomLayout>为 是不可能的,因为public void Apply(CustomGridLayout dataViewer)无法将 aCustomLayout作为输入处理让我举个例子:

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>,但试图将其用作协变接口 - 这是不可能的。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章