将类型为T的数组转换为类型I的数组,其中T在C#中实现I

Adr*_*lie 4 c# arrays ienumerable list

我正在尝试用C#完成一些我在Java中轻松完成的工作.但有点麻烦.我有一个未定义数量的T类型的对象数组.A实现了一个接口I.我需要一个I的数组,它是所有数组中所有值的总和.假设没有数组将包含相同的值.

这个Java代码有效.

ArrayList<I> list = new ArrayList<I>();
for (Iterator<T[]> iterator = arrays.iterator(); iterator.hasNext();) {
    T[] arrayOfA = iterator.next();
    //Works like a charm
    list.addAll(Arrays.asList(arrayOfA));
}

return list.toArray(new T[list.size()]);
Run Code Online (Sandbox Code Playgroud)

但是这个C#代码没有:

List<I> list = new List<I>();
foreach (T[] arrayOfA in arrays)
{
    //Problem with this
    list.AddRange(new List<T>(arrayOfA));
    //Also doesn't work
    list.AddRange(new List<I>(arrayOfA));
}
return list.ToArray();
Run Code Online (Sandbox Code Playgroud)

所以很明显,我需要的阵列以某种方式获得T[]IEnumerable<I>要添加到列表中,但我不知道这样做的最好方法是什么?有什么建议?

编辑:在VS 2008中开发但需要为.NET 2.0编译.

Mar*_*ell 7

编辑为2.0; 它可以成为:

static void Main() {
    IEnumerable<Foo[]> source = GetUndefinedNumberOfArraysOfObjectsOfTypeT();
    List<IFoo> list = new List<IFoo>();
    foreach (Foo[] foos in source) {
        foreach (IFoo foo in foos) {
            list.Add(foo);
        }
    }
    IFoo[] arr = list.ToArray();
}
Run Code Online (Sandbox Code Playgroud)

怎么样(在.NET 3.5中):

I[] arr = src.SelectMany(x => x).Cast<I>().ToArray();
Run Code Online (Sandbox Code Playgroud)

要在上下文中显示:

using System.Collections.Generic;
using System.Linq;
using System;
interface IFoo { }
class Foo : IFoo { //  A implements an interface I
    readonly int value;
    public Foo(int value) { this.value = value; }
    public override string ToString() { return value.ToString(); }
}
static class Program {
    static void Main() {
        // I have an undefined number of arrays of objects of type T
        IEnumerable<Foo[]> source=GetUndefinedNumberOfArraysOfObjectsOfTypeT();
        // I need an array of I at the end that is the sum of
        // all values from all the arrays. 
        IFoo[] arr = source.SelectMany(x => x).Cast<IFoo>().ToArray();
        foreach (IFoo foo in arr) {
            Console.WriteLine(foo);
        }
    }
    static IEnumerable<Foo[]> GetUndefinedNumberOfArraysOfObjectsOfTypeT() {
        yield return new[] { new Foo(1), new Foo(2), new Foo(3) };
        yield return new[] { new Foo(4), new Foo(5) };
    }
}
Run Code Online (Sandbox Code Playgroud)


Dan*_*ert 5

这里的问题是C#不支持泛型中的协方差(至少在C#4.0之前,我认为),因此泛型类型的隐式转换将不起作用.

你可以试试这个:

List<I> list = new List<I>();
foreach (T[] arrayOfA in arrays)
{
    list.AddRange(Array.ConvertAll<T, I>(arrayOfA, t => (I)t));
}
return list.ToArray();
Run Code Online (Sandbox Code Playgroud)

对于那些在这个问题上遇到问题且使用.NET 3.5的人来说,这是一种使用Linq做同样事情的更紧凑的方式.

List<I> list = new List<I>();
foreach (T[] arrayOfA in arrays)
{
    list.AddRange(arrayOfA.Cast<I>());
}
return list.ToArray();
Run Code Online (Sandbox Code Playgroud)