以下代码将在方法调用p1
的参数p2
和NewMethod<T>(p1, p2);
上收到两个错误。
p1
:无法将IQueryable<ICollection<Class1>>
转换为IQueryable<ICollection<T>>
?p2
:无法将IEnumerable<Class1>
转换为IEnumerable<T>
如何修复方法调用?
public interface IBase<out T> { T Prop1 { get; } }
class Class1 : IBase<int> { public int Prop1 { get; set; } }
static IEnumerable<T> NewMethod<T, U>(IQueryable<ICollection<T>> exist, IEnumerable<T> bs)
where T : IBase<U>
{
return null;
}
public IEnumerable<T> Existed<T>(IEnumerable<T> p2)
{
.....
if (typeof(T) == typeof(Class1)) {
IQueryable<ICollection<T>> p1 = null;
return result = NewMethod<Class1, int>(p1, p2);
} .....
}
这是协方差还是反方差问题?
答案 0 :(得分:0)
OP最初询问了一个关于为什么泛型不使用ICollection<T>
的问题。在我回答之后,OP改为提出有关IEnumerable<T>
的不同问题,因此这个答案不再适用。
这是协方差还是反方差问题?
是的,由于ICollection<T>
不是协变的,编译器无法用Class1
代替IBase<U>
。
尝试使用IEnumerable<T>
代替ICollection<T>
(IEnumerable<T>
是协变的)。
你为什么不能这样做?
public IEnumerable<T> Existed<T, U>(IEnumerable<T> bands) where T : IBase<U> {
IQueryable<IEnumerable<T>> p1 = null;
IEnumerable<T> p2 = null;
return NewMethod<T, U>(p1, p2);
}
答案 1 :(得分:-2)
需要多种类型的铸造。
public IEnumerable<T> Existed<T>(IEnumerable<T> p2) // where T : IBase<U>
{
if (typeof(T) == typeof(Class1)) {
IQueryable<ICollection<T>> p1 = null;
return NewMethod<Class1, int>( // Type parameter are assigned
p1 as IQueryable<ICollection<Class1>>,
p2 as IEnumerable<Class1>
) as IEnumerable<T>;
}
....
}