Does projecting a list using LINQ return a list of null values?

When I try to run the projected list in the BuildTypes method, I get a list of null values. I also tried using .Cast (), but I get an error that some properties cannot be selected. I can post an error if this is helpful. Here is my code:

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

Therefore, I would call it as follows:

 var auditActorTypes = BuildTypes<AuditActorType>(auditActorTypesXml) 

I have a ton of types that I need to extract from an XML file and don’t want to duplicate the code for each type.

+4
source share
3 answers

You are trying to use an anonymous object as a type T that cannot be executed. An anonymous type is its own unique type and in no way associated with the passed T

Instead, you can put the restriction of new() on type T so that it means the default constructor, and then instead of anonymous type, run 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; } 

This assumes, of course, that Id , Name , EntityStatus , DateCreated and DateModified are all properties of the EntityValueType base.

+7
source

You cannot do this with the current code, since new { } creates an anonymous type that is not related to T (it is neither a child, nor has type T). Instead, you can implement Id , Name , EntityStatus , DateCreated and DateModified as properties in the EntityValueType class and change:

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

To:

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

Indicates that any type argument passed to our method should have a constructor without parameters, which allows you to use an object of type T to actually build it, mainly by changing:

 select new { ... } as T 

To:

 select new T { ... } 

Final result:

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

Change code:

 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
source

Source: https://habr.com/ru/post/1384999/


All Articles