Een geprojecteerde lijst casten met LINQ retourneert een lijst met null-waarden?

Wanneer ik de geprojecteerde lijst in de BuildTypes-methode cast, krijg ik een lijst met null-waarden. Ik heb ook geprobeerd de .Cast() te gebruiken, maar ik krijg een foutmelding dat sommige eigenschappen niet kunnen worden gecast. Ik kan de fout posten als deze nuttig is. Hier is mijn code:

public class AuditActionType: EntityValueType
{
}

private List BuildTypes(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;
} 

Dus ik zou het zo willen noemen:

var auditActorTypes = BuildTypes(auditActorTypesXml)

Ik heb een heleboel typen die ik uit een XML-bestand moet halen en ik wil geen code voor elk type dupliceren.

4

3 antwoord

U probeert een anoniem object te casten als type T , wat niet kan worden gedaan. Het anonieme type is zijn eigen unieke type en heeft op geen enkele manier betrekking op de T die is ingeleverd.

In plaats daarvan zou u de nieuwe() -beperking op type T kunnen opgeven om aan te geven dat er een standaardconstructor nodig is en voer dan een nieuwe T() uit in plaats van een nieuw anoniem type te maken:

private List BuildTypes(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;
} 

Dit gaat er natuurlijk van uit dat Id , Naam , EntityStatus , DateCreated en DateModified zijn alle eigenschappen van de basis EntityValueType .

7
toegevoegd
@ J.Kommer: goed punt.
toegevoegd de auteur James Michael Hare, de bron
+1 om me er tegen te slaan. Het is misschien de moeite waard te vermelden dat Id / Name /etc moet bestaan ​​op EntityValueType .
toegevoegd de auteur Johannes Kommer, de bron

U kunt dit niet doen met uw huidige code als nieuw {} een anoniem type dat geen relatie heeft met T (het is geen kind, ook niet van het type T). Wat u in plaats daarvan kunt doen is implementeren Id , Naam , EntityStatus , DateCreated en DateModified als eigenschappen in uw EntityValueType -klasse en wijzigen:

private List BuildTypes(XDocument xDocument) where T: EntityValueType

Naar:

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

Dit geeft aan dat elk type argument dat aan onze methode wordt doorgegeven, een parameterloze constructor moet hebben waarmee het mogelijk is om een ​​object van het type T generiek te construeren door het wijzigen van:

select new { ... } as T

Naar:

select new T { ... }

Eindresultaat:

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

Wijzig code:

private List BuildTypes(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
toegevoegd
@James Michael Hare, @ DDiVita - Ja, ik heb het verkeerd begrepen, bedankt voor je punten.
toegevoegd de auteur Reza ArabQaeni, de bron
U hebt de nieuwe() beperking nodig
toegevoegd de auteur James Michael Hare, de bron
@RedHat: Geen zorgen, het was een kleine oversite, ik dacht dat je het meende :-) Ik zal je nu een +1 geven.
toegevoegd de auteur James Michael Hare, de bron