我创建了这个简单的通用接口:
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] 删除。
我来说两句