使用LINQ强制转换投影列表将返回空值列表

本文关键字:列表 返回 空值 投影 转换 LINQ 使用 | 更新日期: 2023-09-27 18:16:53

当我尝试在BuildTypes方法中转换预计列表时,我得到一个空值列表。我也尝试使用. cast(),但我得到一个错误,一些属性不能转换。我可以张贴错误,如果它是有帮助的。下面是我的代码:

public class AuditActionType: EntityValueType
{
}
private List<T> BuildTypes<T>(XDocument xDocument) where T: EntityValueType
{
    var types = 
        (from ty in xDocument.Descendants("RECORD")
         select new
            {
                Id = GenerateGuid(),
                Name = ty.Element("Name").Value,
                EntityStatus = _activeEntityStatus,
                DateCreated = DateTime.Now,
                DateModified = DateTime.Now
            } as T).ToList();
    return types;
} 

所以我可以这样命名它:

var auditActorTypes = BuildTypes<AuditActorType>(auditActorTypesXml)

我需要从XML文件中提取大量类型,并且不想为每种类型复制代码。

使用LINQ强制转换投影列表将返回空值列表

您正在尝试将匿名对象强制转换为类型T,这是无法完成的。匿名类型是它自己的唯一类型,与传入的T没有任何关系。

相反,您可以在类型T上提供new()约束,以表示它需要一个默认构造函数,然后执行new T()而不是创建一个新的匿名类型:

private List<T> BuildTypes<T>(XDocument xDocument) where T: EntityValueType, new()
{
    var types = 
        (from ty in xDocument.Descendants("RECORD")
         select new T()
            {
                Id = GenerateGuid(),
                Name = ty.Element("Name").Value,
                EntityStatus = _activeEntityStatus,
                DateCreated = DateTime.Now,
                DateModified = DateTime.Now
            }).ToList();
    return types;
} 

当然,这是假设IdNameEntityStatusDateCreatedDateModified都是基础EntityValueType的属性。

你不能用你当前的代码这样做,因为new { }创建了一个与T没有关系的匿名类型(它既不是子类型,也不是T类型)。你可以做的是在你的EntityValueType类上实现Id, Name, EntityStatus, DateCreatedDateModified作为属性并更改:

private List<T> BuildTypes<T>(XDocument xDocument) where T: EntityValueType

:

 private List<T> BuildTypes<T>(XDocument xDocument) where T: EntityValueType, new()

指定传递给方法的任何类型实参必须有一个无参数构造函数,允许通过以下更改实际构造T类型对象:

select new { ... } as T

:

select new T { ... }

最终结果:

public class EntityValueType
{
    public Guid Id { get; set; }
    public string Name { get; set; }
    // Change this to the correct type, I was unable to determine the type from your code. 
    public string EntityStatus { get; set; }
    public DateTime DateCreated { get; set; }
    public DateTime DateModified { get; set; }
}
public class AuditActionType: EntityValueType
{
}
private List<T> BuildTypes<T>(XDocument xDocument) where T: EntityValueType, new()
{
    return (from ty in xDocument.Descendants("RECORD")
        select new T
            {
                Id = GenerateGuid(),
                Name = ty.Element("Name").Value,
                EntityStatus = _activeEntityStatus,
                DateCreated = DateTime.Now,
                DateModified = DateTime.Now
            }).ToList();
} 

更改代码:

private List<T> BuildTypes<T>(XDocument xDocument) where T: EntityValueType, new()
{
    var types = 
        (from ty in xDocument.Descendants("RECORD")
         select new T()
            {
                Id = GenerateGuid(),
                Name = ty.Element("Name").Value,
                EntityStatus = _activeEntityStatus,
                DateCreated = DateTime.Now,
                DateModified = DateTime.Now
            }).ToList();
    return types;
}