IEnumerable到T []的数组

时间:2014-02-20 21:44:37

标签: c# generics casting

问题标题可能不正确。我有以下变量

IEnumerable x = // some IEnumerable
System.Type y = // some type

如何迭代x以生成包含y类型项的数组?

当我查看互联网时,我发现:

public T[] PerformQuery<T>(IEnumerable q)
{                         
        T[] array = q.Cast<T>().ToArray();
        return array;
}

注意我无法调用该方法,因为Perform y的类型为System.Type,换句话说,将其称为PerformQuery<typeof(y)>(x);PerformQuery<y>(x);会给我一个编译错误。


修改

这就是我遇到这个问题的原因。我有网络服务,我发布了两件事。我想要查询的表的类型(示例typeof(Customer)),以及实际的字符串查询示例“Select * from customers”

    protected void Page_Load(object sender, EventArgs e)
    {
        // code to deserialize posted data
        Type table = // implement that here
        String query = // the query that was posted

        // note DB is of type DbContext
        IEnumerable q = Db.Database.SqlQuery(table, query );

        // here I will like to cast q to an array of items of type table!

3 个答案:

答案 0 :(得分:6)

您可以使用表达式树:

public static class MyExtensions
{
    public static Array ToArray(this IEnumerable source, Type type)
    {
        var param = Expression.Parameter(typeof(IEnumerable), "source");
        var cast = Expression.Call(typeof(Enumerable), "Cast", new[] { type }, param);
        var toArray = Expression.Call(typeof(Enumerable), "ToArray", new[] { type }, cast);
        var lambda = Expression.Lambda<Func<IEnumerable, Array>>(toArray, param).Compile();

        return lambda(source);
    }
}

它会为您生成x => x.Cast<Type>().ToArray(),并在运行时知道Type

用法:

IEnumerable input = Enumerable.Repeat("test", 10);
Type type = typeof(string);

Array result = input.ToArray(type);

答案 1 :(得分:4)

var ObjectsOfType_y = x.OfType<object>().Where(x => x.GetType() == y);

请注意,这将返回IEnumerable<object>。没有办法解决这个问题,因为y(Type)表示的类型在编译时是未知的。

答案 2 :(得分:1)

根据我的理解,IENumerable只包含一种类型。如果我理解你要做的事情,那么IENumerable只包含y类型的对象。如果y需要更改,您可以编写扩展方法:

public static T[] ToArray<T>(this IEnumerable<T> source)
    {
        int length = System.Linq.Enumerable.Count(source);
        T[] newArray = new T[length];
        int i = 0;
        foreach(T item in source)
        {
            newArray[i] = item;
        }
        return newArray;
    }