2017-01-05 21 views
1

在C#中,我想在那里我知道“T”支持界面“IMyInterface的”,并采取“T”型数组:在C#中,如何将IEnumerable <IMyInterface>的数组转换为IEnumerable <T>?

  1. 将它转换为“IMyInterface的”
  2. 呼叫数组在该阵列上将过滤列表的方法
  3. 将其重新转换回原始类型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>; 

这似乎总是返回null(而不是滤波阵列转换回IEnumerable的< T>。

这里的任何建议,我可能会做错什么,以及如何正确地将一个接口数组转换回T型数组?

+0

从'T'投射到'IMyInterface'是否工作在没有IEnumerable的情况下? – kat1330

+2

你为什么需要演员?你不能过滤原始的'IEnumerable '吗? –

+0

@LucMorin - 我在IEnumerable 上做过滤器,但我需要将其转换回原来的类型,因为我的下一行代码依赖于它..我已更新问题以使其更清晰 – leora

回答

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

无需迭代整个集合来投射每个对象。如果集合包含* not * a'T'(因此为什么'as'转换返回null),那么这也会崩溃 – Rob

+0

@Rob OP特别说:'我想要一个类型为“T”的数组,我知道“T”支持接口“IMyInterface”,那么它为什么会崩溃。 – CodingYoshi

+0

因为潜在的'过滤'可能会增加收藏。这里没有类型安全。事实上,如果你能证明只有'T'将被包含在集合中,那么实际上并不需要演员阵容。 – Rob

0

要么你不需要它转换为IEnumerable<IMyInterface>,或运行时已经正确地阻止你写bug的代码。

让我们小例子:

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) 

我们能假设Apple : IMyInterface给它一堆IEnumerable<Apple>。然后你试着把它投到IEnumerable<T>那里T = Banana和繁荣,代码破碎。

相关问题