无法将IEnumerable <class1>转换为IEnumerable <t>?

时间:2016-02-23 22:13:52

标签: c#

以下代码将在方法调用p1的参数p2NewMethod<T>(p1, p2);上收到两个错误。

  1. p1:无法将IQueryable<ICollection<Class1>>转换为IQueryable<ICollection<T>>
  2. p2:无法将IEnumerable<Class1>转换为IEnumerable<T>
  3. 如何修复方法调用?

    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);
      } .....
    }
    

    这是协方差还是反方差问题?

2 个答案:

答案 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>;
  }
  ....
}