Reputation: 45
I have a generic property that's meant to represent a list of physical addresses:
public T PhysicalAddressList
{
get => GetPhysicalAddressListValue<T>(_physicalAddressList);
set => _physicalAddressList = SetPhysicalAddressListValue<T>(value);
}
I'm using a field for the get
and set
. However, I need to run a few changes on the field throughout the duration of this base class's lifetime. For that reason the field _physicalAddressList
is explicitly declared as:
List<PhysicalAddressDTO> _physicalAddressList;
Naturally, this means I'll have to convert it from the generic to the definition (set
) and back to the generic (get
) using methods. Now, I've managed to work out the set
aspect of the property fairly easily.
The get
is the issue I have. Simply put, I cannot cast a List through to a generic type:
private T GetPhysicalAddressListValue<TPhysicalAddress>(List<PhysicalAddressDTO>
physicalAddressList)
{
if (physicalAddressList is T)
return (T)physicalAddressList;
else
{
Type genericType = typeof(T);
// Code to convert parameter into datatype specified in genericType
if (convertedPhysicalAddressList is T)
return (T)convertedPhysicalAddressList; // Cannot convert type 'List<PhysicalAddressDTO>' to 'T'
}
}
I'm confused because ideally, I'd normally get this error at runtime if the two aren't compatible. However, this error appears while coding... after ensuring the type being cast matches the expected generic.
Why can other types can be cast to generics while List's cannot?
Side note: (IEnumerables don't give me this problem. But here, I can't use an IEnumerable because... you know... T
isn't an IEnumerable
).
So, any suggestions would be much appreciated. How do I go about this?
Upvotes: 0
Views: 484
Reputation: 152
IEnumerable<T>
is covariant interface, but IList<T>
is not.
Covariance means that you can do implicit conversion of an array of a more derived type to an array of a less derived type:
IEnumerable<String> strings = new List<String>();
IEnumerable<Object> objects = strings;
There are many answers why IList<T>
is not covariant, see for example here: ICollection<T> not Covariant? or here: Why can I not assign a List of concrete types to a List of that concrete's interface?.
Is it possible to avoid converting from one list to another and use list of objects of the base type everywhere? If no, you can use the following construction:
physicalAddressList.Cast<PhysicalAddressDTO>().ToList()
Upvotes: 1