动态上传相同类型实例的数组

时间:2015-03-04 12:28:07

标签: c# type-conversion upcasting

鉴于此linqpad代码:

interface I {}
public class A : I {}
public class B : A {}
void Main()
{
    var i = new List<I>(new I[] { new A(), new B(), new A(), new B() });
    i.GroupBy(_ => _.GetType()).Select(_ => _.ToArray()).Dump();
}

将这些项目转换为实际派生类型的IEnumerables的最有效方法是什么?

我有一个带签名DoStuffToArray<T>(IEnumerable<T> items)的方法 我需要为列表i中的每个不同类型动态调用它一次。这是一个需要使用派生类型调用的库方法,而不是接口。

我已经设法使用此方法获得两个类型化数组,有更好的方法吗?

var typeGroup = i.GroupBy(_ => _.GetType()).ToArray();
var arrays = typeGroup.Select(_ => Array.CreateInstance(_.Key, _.Count())).ToArray();   
for (int ai = 0; ai < typeGroup.Length; ai++)
{
    var grouping = typeGroup[ai].ToArray();
    int index = 0;
    Array.ForEach(grouping, _ => arrays[ai].SetValue(_, index++));
}
arrays.Dump("typed arrays");

2 个答案:

答案 0 :(得分:1)

您正在寻找OfType<T>()

var i = new List<I>(new I[] { new A(), new B(), new A(), new B() });
var ayes = i.OfType<A>();
var bees = i.OfType<B>(); 

DoStuffToArray(ayes);
DoStuffToArray(bees);

实例:http://rextester.com/HQWP13863

答案 1 :(得分:0)

怎么样:

List<I> i = new List<I>(new I[] {new A(), new B(), new A(), new B()});

var types = i.Select(item => item.GetType()).Distinct();

foreach (var instances in types.Select(type => i.Where(item =>item.GetType() == type))) 
{   DoStuffToArray(instances); }

这是我能想到的简短......

您将类型收集为Disctinct列表,然后迭代提取。但是,这种方法使用了很多反射,因此性能不是最佳的。