使用LINQ投影列表返回了一个空值列表?

4
当我尝试在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文件中提取,但不想为每种类型复制代码。
3个回答

7

您试图将匿名对象强制转换为类型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 属性的情况下。

+1,你比我先完成了。可能值得一提的是,Id / Name / 等等需要存在于 EntityValueType 上。 - Johannes Kommer

4
您当前的代码无法实现此功能,因为new { }创建了一个匿名类型,它与T没有任何关系(既不是子类,也不是T类型)。您可以在EntityValueType类中实现IdNameEntityStatusDateCreatedDateModified属性,并将以下内容更改:
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

To:

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

1

更改代码:

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

1
你需要使用new()约束。 - James Michael Hare
@James Michael Hare,@DDiVita - 是的,我犯了错误,感谢你们的指正。 - Reza ArabQaeni
@RedHat:没关系,这只是一个小疏忽,我以为你是这个意思 :-) 我现在会给你点赞。 - James Michael Hare

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接