When I try to Cast the projected list in the BuildTypes method, I get a list of null values. I have also tried using the .Cast(), but I get an error that some of the properties cannot be cast. I can post the error if it 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;
}
So I would call it like this:
var auditActorTypes = BuildTypes<AuditActorType>(auditActorTypesXml)
I have a ton of types I need to pull from an XML file and didn't want to duplicate code for each type.
You are trying to cast an anonymous object as type T, which cannot be done. The anonymous type is it's own unique type and in no way related to the T passed in.
Instead, you could supply the new() constraint on type T to mean it needs a default constructor, and then perform a new T() instead of creating a new anonymous type:
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 is assuming, of course, that Id, Name, EntityStatus, DateCreated, and DateModified are all properties of the base EntityValueType.
You cannot do this with your current code as new { } creates an anonymous type which has no relationship with T (it is neither a child, nor is it of type T). What you could do instead is implement Id, Name, EntityStatus, DateCreated and DateModified as properties on your 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()
Which specifies that any type argument passed to our method must have a parameterless constructor which allows use to actually construct an object of type T generically by changing:
select new { ... } as T
To:
select new T { ... }
End 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();
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With