将List <anonymous type>传递给C#中需要List <T>的方法

Nib*_*Pig 2 c# generics

这可能吗?

var cats = catsource.Select(c => new
{
    CatId = c.catId,
    Name = c.Name,
}).ToList();
Run Code Online (Sandbox Code Playgroud)

var myCatObject = new CatData(cats);

这不起作用,因为编译器说它无法转换cats为List<T>.

cats是一种匿名类型,CatData是:

public class CatData<T>
{
    public int total;
    public int records;
    public List<T> records;

    public CatData(List<T> dataObjects, int totalRecords, int numberOfRows)
    {
        total = (int)Math.Ceiling((double)totalRecords / numberOfRows);
        records = totalRecords;
        rows = dataObjects;
    }
}
Run Code Online (Sandbox Code Playgroud)

有任何想法吗?


编辑:

所以我已经完成了这个代码,但仍然存在一个问题:

 public class CatData
 {
     public int total;
     public int records;
     public List<T> rows;

     private CatData(List<T> dataObjects, int totalRecords, int numberOfRows)
     {
         total = (int)Math.Ceiling((double)totalRecords / numberOfRows);
         records = totalRecords;
         rows = dataObjects;
     }

     public static CatData<T> Create(List<T> dataObjects, int totalRecords, int numberOfRows)
     {
         return new CatData<T>(dataObjects, totalRecords, numberOfRows);
     }
 }
Run Code Online (Sandbox Code Playgroud)

此代码在每个<T>说法实例上都有错误

无法解析符号T.

如果我改变了public class CatData<T>它要编译的类,但是我不能拥有这个代码:

CatData.Create(records, totalRecords, rows);

因为它说

错误的类型参数数量.


更新解释我想要的东西:

我想创建一个具有匿名类型的对象列表

var someList = someCollection.Select(new { ... });

我想创建一个将它们存储为的对象 List<anonymous>

var myObject = new myObject(someList, 5);

所以我可以这样做:

myObject.someValue; // 5 (stored it in the constructor) myObject.myList.Count(); // can count how many anonymous objects are in there

也许我应该把它存储为List<object>.


我真的不明白,也许我只是有点太厚了.我刚刚结束了这个:

public CatData(List<object> dataObjects, int totalRecords, int numberOfRows) 作为我的构造函数.

var catData = new CatData(records.Cast<object>().ToList(), totalRecords, rows);

ang*_*son 10

您需要定义工厂方法.

在调用方法时推断泛型(如果可能),但在调用构造函数时则不推断.

所以加上这个:

public static class CatData
{
    public static CatData<T> Create<T>(List<T> cats)
    {
        return new CatData<T>(cats);
    }
}
Run Code Online (Sandbox Code Playgroud)

像这样使用:

var data = CatData.Create(cats);
Run Code Online (Sandbox Code Playgroud)

Eric Lippert 在这里也提供了一个答案,讨论了为什么不允许这样做的一些注意事项.

随着新的Roslyn编译器的引入,新功能可能更有可能出现,因为它意味着1个更改可以应用于多种语言并且更容易实现,这可能是这次讨论的新生活,显然现在正在考虑对通用构造函数参数的支持类型推断:DamienG的博客,可能的C#6.0特性


由于这个技巧是否真的有效,似乎有些混乱,这里有一个完整的LINQPad程序,它演示了:

void Main()
{
    var test = new[]
    {
        new { name = "Test", id = 42 },
        new { name = "Test 2", id = 17 }
    }.ToList();
    CatData.Create(test);
}

public class CatData<T>
{
    public CatData(List<T> list)
    {
    }
}

public static class CatData
{
    public static CatData<T> Create<T>(List<T> list)
    {
        return new CatData<T>(list);
    }
}
Run Code Online (Sandbox Code Playgroud)

这很好用,说明在同一名称空间和程序集中同时拥有静态非泛型类和具有相同类名的泛型类是完全合法的.

在.NET框架中也应该有充分的证据,因为Tuple存在多个版本.