在C#中,如何将我的数组从IEnumerable <imyinterface>转换为IEnumerable <t>?

时间:2017-01-05 00:53:15

标签: c# arrays casting ienumerable

在C#中,我想要一个Type&#34; T&#34; 我知道的地方&#34; T&#34;支持界面&#34; IMyInterface &#34;和

  1. 将其投射为&#34; IMyinterface&#34;
  2. 的数组
  3. 在该数组上调用将过滤列表的方法
  4. 将其转换回原始类型T列表。
  5. 上面的1和2工作正常,但我遇到了第3步的问题。

    这是我的代码:

    IEnumerable<IMyInterface> castedArray = originalTypedArray as IEnumerable<IMyInterface>;
    
    if (castedArray != null)
    {
        var filteredArray = castedArray.Where(r => r.Ids.Contains(MyId)).ToList();
    
         IEnumerable<T> castedBackToOriginalTypeArray = filteredArray as IEnumerable<T>;
         if (castedBackToOriginalTypeArray == null)
         {
              current = new List<T>();
         }
         else
         {
            current = castedBackArray;
         }
    
         // I need to cast back, because only my Type T has the .Id property
         List<int> ids = current.Select(r => r.Id).ToList();
     }
    

    问题出在这一行:

     IEnumerable<T> castedBackToOriginalTypeArray = filteredArray as IEnumerable<T>;
    

    总是看起来返回null(而不是将过滤后的数组强制转换回IEnumerable&lt; T&gt;。

    这里有任何建议我可能做错了什么以及如何纠正将接口数组强制转换为T类数组?

2 个答案:

答案 0 :(得分:2)

这对我有用:

public class A : IA {

}


public interface IA {

}

List<A> l = new List<A> { new A(), new A(), new A() };
IEnumerable<IA> ias = l.Cast<IA>();
IEnumerable<A> aTypes = ias.Cast<A>();

答案 1 :(得分:0)

您不需要将其强制转换为IEnumerable<IMyInterface>,或者运行时已正确阻止您编写错误代码。

让我们举个更小的例子:

void SomeMethod<T>(IEnumerable<T> originalTypedArray, int MyId) 
    where T : class, IMyInterface
//  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this is important 
{
    if (originalTypedArray != null)
    {
        var filteredArray = originalTypedArray.Where(r => r.Ids.Contains(MyId));

        // No need to cast to `IEnumerable<T>` here - we already have ensured covariance
        // is valid in our generic type constraint
        DoSomethingExpectingIEnumerableOfIMyInterface(filteredArray);
    }
}
void DoSomethingExpectingIEnumerableOfIMyInterface(IEnumerable<IMyInterface> src)
{
    foreach (var thing in src)
    {

    }
}

但是,如果您将集合作为IEnumerable<T>,那么运行时正确地使投射失败:

void SomeMethod<T>(IEnumerable<IMyInterface> originalTypedArray, int MyId)

我们可以假设IEnumerable<Apple>给它一堆Apple : IMyInterface。然后,您尝试将其转换为IEnumerable<T> T = Banana并繁荣,代码损坏。