C# 通过泛型类使用接口实现

C# 通过泛型类使用接口实现,c#,generics,C#,Generics,我尝试通过泛型类使用接口实现。想知道一些抽象的魔力,但是用这种方法会得到编译器错误 cannot convert from 'GClass<PosClass>' to 'GClass<IPos>' 无法从“GClass”转换为“GClass” 下面是一个简化的示例: //非常简单,只有数据访问,没有内部操作 类GClass{ T值; 公共GClass(T值){ 这个值=值; } 公共部门得不到{ 返回值; } } //简单接口 接口IPO{ int GetPos();

我尝试通过泛型类使用接口实现。想知道一些抽象的魔力,但是用这种方法会得到编译器错误

cannot convert from 'GClass<PosClass>' to 'GClass<IPos>'
无法从“GClass”转换为“GClass”
下面是一个简化的示例:

//非常简单,只有数据访问,没有内部操作
类GClass{
T值;
公共GClass(T值){
这个值=值;
}
公共部门得不到{
返回值;
}
}
//简单接口
接口IPO{
int GetPos();
}
//简单实现
类别:首次公开募股{
//接口实现
公共int GetPos(){
返回1;
}
public int GetAnotherImportantData(){
返回-1;
}
}
类主故障{
公共int DoUsingInterface(GClass interfaceableItem){
//仅使用接口方法进行工作
返回interfaceableItem.Get().GetPos();
}
公共int-dousingheritation(){
GClass item=newgclass(newposclass());
//下一行错我了
//无法从“GClass”转换为“GClass”
var r=双界面(项目);
//所以,接下来我应该使用PosClass执行几个方法
return item.Get().GetAnotherImportantData();
}
}

有什么建议吗?可能是我错过了一些棘手的演员阵容?

这很有效,我将在底部添加一个解释:

interface IGClass<out T>
{
    T Get();
}
class GClass<T> : IGClass<T>
{
    T value;
    public GClass(T value)
    {
        this.value = value;
    }
    public T Get()
    {
        return value;
    }
}

//Simple interface
interface IPos
{
    int GetPos();
}

//Simple realization
class PosClass : IPos
{
    //Interface realization
    public int GetPos()
    {
        return 1;
    }
    public int GetAnotherImportantData()
    {
        return -1;
    }
}

class MainTrouble
{
    public int DoUsingInterface(IGClass<IPos> interfaceableItem)
    {
        //Do work using only interface methods
        return interfaceableItem.Get().GetPos();
    }

    public int DoUsingInheritance()
    {
        GClass<PosClass> item = new GClass<PosClass>(new PosClass());

        var r = DoUsingInterface(item);

        return item.Get().GetAnotherImportantData();
    }
}
接口类
{
T Get();
}
类别G类别:IGClass
{
T值;
公共GClass(T值)
{
这个值=值;
}
公共部门得不到
{
返回值;
}
}
//简单接口
接口IPO
{
int GetPos();
}
//简单实现
类别:首次公开募股
{
//接口实现
公共int GetPos()
{
返回1;
}
public int GetAnotherImportantData()
{
返回-1;
}
}
类主故障
{
公共int DoUsingInterface(IGClass interfaceableItem)
{
//仅使用接口方法进行工作
返回interfaceableItem.Get().GetPos();
}
公共int-dousingheritation()
{
GClass item=newgclass(newposclass());
var r=双界面(项目);
return item.Get().GetAnotherImportantData();
}
}
您希望
GClass
成为
GClass
。您知道这是可行的,因为您知道GClass是“只读”的。所有
PosClass
都是
ipo
,但显然不是所有
ipo
都是
PosClass
。因此,要让第一个成功,两者都必须是真实的

因此,您需要确保编译器知道您所知道的:类GClass实际上是只读的。因为你只需要第一部分,这永远是真的。这就是问题所在。它被调用并且只在接口上工作,这就是为什么我添加了一个额外的接口

让我们用更简单、更形象的例子来说明这一点。狼是一种动物。羊是一种动物。但是羊的名单不是动物的名单。。。如果是的话,我可以加上一只狼,因为狼是一种动物。所以你需要的是一个界面“是的,从阅读上看,它们都是动物。比如
IEnumerable
IEnumerable
是一个
IEnumerable
,因为它是声明协变的,这是唯一可能的,因为它只在一个方向上工作:读取

基于解决离您不远的问题,它不会起作用,因为
GClass
GClass
之间没有关系。实际上,
GClass
的列表并不是
GClass
的列表


为了帮助您更好地理解这些问题,我建议您阅读有关协方差和逆变换的内容。

我一直在努力理解协方差,但我想我明白您的意思。这本质上等同于执行类似以下操作的列表:IPos myVar=new PosClass()然后只能使用
myVar
,就好像它是一个
IPos
而不是
PosClass()
(因为你需要一个硬演员)?基本上是的。