2017-01-05 24 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和繁榮,代碼破碎。

相關問題