简体   繁体   中英

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

In C#, I want to take an array of Type "T" where I know "T" supports the interface "IMyInterface " and:

  1. Cast it as array of "IMyinterface"
  2. Call a method on that array that will filter the list
  3. Cast it back to the original type T list.

1 and 2 above work fine, but I am running into issues on step #3.

Here is my code:

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

The issue is on this line:

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

That always seem to return null (instead of the filtered array cast back to IEnumerable<T>.

Any suggestions here for what I might be doing wrong and how to correct cast an array of an interface back into an array of type T?

This works for me:

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

Either you don't need to cast it to IEnumerable<IMyInterface> , or the runtime has correctly prevented you from writing buggy code.

Let's take a smaller example:

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)
    {

    }
}

However, if you're not getting the collection as IEnumerable<T> , then the runtime is correctly failing the cast:

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

We could give it a bunch of IEnumerable<Apple> assuming Apple : IMyInterface . Then you try to cast it to IEnumerable<T> where T = Banana and boom, code broken.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM