通行证列表<;匿名类型>;进入需要List<;T>;在C#中

本文关键字:lt gt List 类型 通行证 列表 | 更新日期: 2023-09-27 17:59:16

这可能吗?

var cats = catsource.Select(c => new
{
    CatId = c.catId,
    Name = c.Name,
}).ToList();

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

有什么想法吗?


编辑:

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

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

此代码在<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);

通行证列表<;匿名类型>;进入需要List<;T>;在C#中

您需要定义一个工厂方法。

在调用方法时(如果可能的话)会推断泛型,但在调用构造函数时不会推断。

所以加上这个:

public static class CatData
{
    public static CatData<T> Create<T>(List<T> cats)
    {
        return new CatData<T>(cats);
    }
}

像这样使用:

var data = CatData.Create(cats);

Eric Lippert也在这里提供了答案,谈到了为什么不允许这样做的一些考虑因素。

随着新Roslyn编译器的推出,新功能可能会有更好的机会出现,因为这意味着一个更改可以应用于多种语言,并且更容易实现,这可能是引发这场讨论的新活力的原因,因为显然支持泛型构造函数参数的类型推理现在正在考虑中: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);
    }
}

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

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

当您调用方法时,泛型类型推理是有效的,因此您应该创建一个工厂方法:

public static class CatData
{
    public static CatData<T> Create<T>(List<T> dataObjects, int totalRecords, int numberOfRows)
    {
        return new CatData<T>(dataObjects, totalRecords, numberOfRows);
    }
}

现在你可以做:

var cats = catsource.Select(c => new
{
    CatId = c.catId,
    Name = c.Name,
}).ToList();
var myCatObject = CatData.Create(cats, cats.Length, cats.Length);

不能使构造函数成为泛型;要实例化一个泛型类,需要指定类参数。

但是,还有一个解决办法:

public static class CatDataHelper
{
    public static CatData<T> MakeCatData<T>(this List<T> list)
    {
        return new CatData<T>(list);
    }
}
//...
var myCatObject = cats.MakeCatData();

不要使用var,而是使用dynamic。

 dynamic cats = catsource.Select(c => new
 {
     CatId = c.catId,
      Name = c.Name,
 }).ToList();