Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/293.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用相关/派生Ts在泛型中进行转换_C#_Generics_Casting - Fatal编程技术网

C# 使用相关/派生Ts在泛型中进行转换

C# 使用相关/派生Ts在泛型中进行转换,c#,generics,casting,C#,Generics,Casting,谁能告诉我如何将rd转换为rb 实际上BaseItem本身也是一个广义类,但为了简单地解决这个问题,没有编写它类基本项/派生项 对于那个些能够理解我面临的真正问题的人来说,这是一个问题 rb = rd; IShape形状; 下面是一个声明的对象 IShape<IBaseShape<long>, long> shape; IShape三角形=新形状()//源自IShape的形状 形状=三角形//问题就在这里。 ITriangle源于IBaseShape。我真的

谁能告诉我如何将
rd
转换为
rb

实际上BaseItem本身也是一个广义类,但为了简单地解决这个问题,没有编写它<代码>类基本项/派生项

对于那个些能够理解我面临的真正问题的人来说,这是一个问题

rb = rd;   
IShape形状;
下面是一个声明的对象

IShape<IBaseShape<long>, long> shape;
IShape三角形=新形状()//源自IShape的形状
形状=三角形//问题就在这里。
ITriangle源于IBaseShape。我真的很感谢你的帮助


结果:我决定不实现out关键字。在我的案例中,它没有带来太多的价值(这是一个持续数月的项目,到处都是泛型)。具体地说,如果考虑在带有关键字和GETTER的接口中实现SET,则使用由Outout关键字修饰的接口中的泛型创建的铸造问题使我想到了两次。总之,如果您从一开始就开始使用它们,它可能会很有用,否则它可能会带来比您想象的更多的问题。

您要寻找的是泛型类型的协方差和逆变。您可以阅读本主题

您要查找的是泛型类型的协方差和逆变。您可以阅读本主题

只要您继续使用接口而不是实际的类,就可以使用协方差/逆变

像这样:

IShape<ITriangle<long>, long> triangle =new Shape<ITriangle<long>,long>(); //Shape derived from IShape

shape = triangle; //here is the problem.
void Main(){
实现接口rb1;
RealizedInterface rd1=新的RealizedInterface();
rb1=rd1;//不起作用
接口rb2;
IInterface rd2=新实现的接口();
rb2=rd2;//有效
}
//在此处定义其他方法和类
类BaseItem{}
类DerivedItem:BaseItem{}
接口接口,其中T:BaseItem{}//注意out关键字!
类RealizedInterface:i接口,其中T:BaseItem{}

只要继续使用接口而不是实际的类,就可以使用协方差/逆变

像这样:

IShape<ITriangle<long>, long> triangle =new Shape<ITriangle<long>,long>(); //Shape derived from IShape

shape = triangle; //here is the problem.
void Main(){
实现接口rb1;
RealizedInterface rd1=新的RealizedInterface();
rb1=rd1;//不起作用
接口rb2;
IInterface rd2=新实现的接口();
rb2=rd2;//有效
}
//在此处定义其他方法和类
类BaseItem{}
类DerivedItem:BaseItem{}
接口接口,其中T:BaseItem{}//注意out关键字!
类RealizedInterface:i接口,其中T:BaseItem{}

如果
IShape
的定义方式是只“检索”第一个类型参数的元素,那么将定义从
IShape
更改为
IShape
,告诉编译器这一点,然后一切都将正常运行(给出足够新的.NET版本)


如果
IShape
的定义方式使您可以通过接口“推送”第一个类型参数的元素,那么这将无法工作。如果将
IShape
隐藏为
IShape
,则如果尝试将
ISquare
推入其中,它将断开。

如果
IShape
的定义方式是只“检索”第一个类型参数的元素,然后将您的定义从
IShape
更改为
IShape
,告诉编译器这一点,然后一切都将正常工作(考虑到.NET的最新版本)


如果
IShape
的定义方式使您可以通过接口“推送”第一个类型参数的元素,那么这将无法工作。如果您将
IShape
隐藏为
IShape
,那么如果您尝试将
ISquare
推到其中,它将中断。

语言将是一个有用的附加标记。另外,如果您想发布代码示例,通常最好突出显示代码并点击
{}
按钮。另外,如果您想发布代码示例,通常最好突出显示代码并点击
{}
按钮。
void Main() {   
    RealizedInterface<BaseItem> rb1;
    RealizedInterface<DerivedItem> rd1 = new RealizedInterface<DerivedItem>();
    rb1 = rd1; // doesn't work

    IInterface<BaseItem> rb2;
    IInterface<DerivedItem> rd2 = new RealizedInterface<DerivedItem>();
    rb2 = rd2; // works
}

// Define other methods and classes here
class BaseItem { }

class DerivedItem : BaseItem { }

interface IInterface<out T> where T:  BaseItem { } // Notice the out keyword!

class RealizedInterface<T> : IInterface<T> where T:BaseItem { }