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

In C#, how can I convert my array from IEnumerable<IMyInterface> to IEnumerable<T>?

在 C# 中,我想获取类型为 "T" 的数组,我知道 "T" 支持接口 "IMyInterface" 和:

  1. 将其转换为 "IMyinterface"
  2. 的数组
  3. 对该数组调用一个方法来过滤列表
  4. 将其转换回原始类型 T 列表。

上面的 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>;

这似乎总是 return null(而不是将过滤后的数组强制转换回 IEnumerable

这里有关于我可能做错了什么以及如何更正将接口数组转换回 T 类型数组的任何建议吗?

这对我有用:

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>();

您不需要将其强制转换为 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 和繁荣,代码损坏。