Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/313.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# 泛型对象需要强制转换,即使它实现了所需的接口_C#_.net_Generics_Interface - Fatal编程技术网

C# 泛型对象需要强制转换,即使它实现了所需的接口

C# 泛型对象需要强制转换,即使它实现了所需的接口,c#,.net,generics,interface,C#,.net,Generics,Interface,不要认为这个标题可以解释我在讲什么,而且它有点难以解释,所以我会让代码来解释。您可以将其复制并粘贴到LINQPad中,并将其作为C#程序运行,或者在visual studio中作为常规C#项目进行必要的调整(例如:将对Dump()的调用更改为Console.Writeline()等)- 请注意,如果在doStuff方法中取消注释该行,它将不会编译 我的问题是,当generic2已经实现了Iab,为什么我需要强制转换?这是协方差吗?我还在.NET3.5上 void Main() { doS

不要认为这个标题可以解释我在讲什么,而且它有点难以解释,所以我会让代码来解释。您可以将其复制并粘贴到LINQPad中,并将其作为C#程序运行,或者在visual studio中作为常规C#项目进行必要的调整(例如:将对Dump()的调用更改为Console.Writeline()等)-

请注意,如果在doStuff方法中取消注释该行,它将不会编译

我的问题是,当generic2已经实现了
Iab
,为什么我需要强制转换?这是协方差吗?我还在.NET3.5上

void Main()
{
    doStuff<a,b>();
}

public void doStuff<TA, TB>()
where TA : class, Ia, new()
where TB : class, Ib, new()
{
    Iab<TA, TB> x = null;

    x = new generic1<TA, TB>();
    x.Go().Dump();

    //x = new generic2<TA>(); // <-Cannot implicitly convert type 'UserQuery.generic2<TA>' to 'UserQuery.Iab<TA,TB>'. An explicit conversion exists (are you missing a cast?)
    x = (Iab<TA, TB>) new generic2<TA>();
    x.Go().Dump();
}

public interface Ia
{}

public interface Ib
{}

public class a : Ia
{}

public class b : Ib
{}

public interface Iab<TA,TB>
where TA : class, Ia, new()
where TB : class, Ib, new()
{
    string Go();
}

public class generic1<TA, TB> : Iab<TA,TB>
where TA : class, Ia, new()
where TB : class, Ib, new()
{
    public string Go()
    {
        return "generic Base called";
    }
}

public class generic2<TA> : Iab<TA,b>
where TA : class, Ia, new()
{
public string Go()
    {
        return "generic Sub called";
    }
}
void Main()
{
doStuff();
}
公共空间
其中TA:class,Ia,new()
其中TB:class,Ib,new()
{
Iab x=null;
x=新的泛型1();
x、 Go().Dump();

//x=new generic2();//我认为这是因为当编译时一个或多个类型(在本例中为
TS
)未知时,您总是会遇到该错误

编译器不能保证使用兼容类型调用
doStuff()
,因此它会强制您强制转换

要了解编译器无法执行此操作的原因,请尝试调用
doStuff()
,如下所示:

public class X: b {}

...

doStuff<a, X>(); // Compiles ok but:
公共类X:b{}
...
doStuff();//编译正常,但:
未处理的异常:System.InvalidCastException:无法将类型为“generic2
1[Demo.Program+X]”的对象强制转换为类型为“Iab
2[Demo.Program+X,Demo.Program+Y]”

因此,您可以使用会使其崩溃的类型调用它;编译器不会默默地让您这样做