Я пытаюсь поддерживать отображение в / из любого типа коллекции, которая реализует ICollection<T>
с помощью отражения, потому что ICollection<T>
требует реализации метода Add.
Это прекрасно работает для большинства распространенных типов коллекций., но терпит неудачу для крайних случаев, таких как LinkedList<T>
, где метод Add скрыт и может быть вызван только путем приведения LinkedList<T>
к ICollection<T>
.
Однако невозможно преобразовать в ICollection<>
, поскольку он не является ковариантным.
Другой вариант, который я рассматривал, заключался в поиске как неявных, так и явных реализаций Add, но я этого не делаюувидеть какую-либо информацию о том, как это сделать, когда интерфейс является общим?
Какой правильный подход был бы выбран?
Обновлен, чтобы показать фрагмент кода, в котором я отражаю от xml до сопоставления объектов.
private object CollectionXmlNodeListToObject(
XmlNodeList nodeList, System.Type collectionType)
{
// this is not possible because ICollection<> is not covariant
object collection = Convert.ChangeType(
CreateInstanceOfType(collectionType), ICollection<>);
Type containedType = collectionType.GetTypeInfo().GenericTypeArguments[0];
foreach (XmlNode node in nodeList)
{
object value = CreateInstanceOfType(containedType);
if (containedType.IsClass && MetaDataCache.Contains(containedType))
value = ToObject(value, node, node.Name);
else
value = node.InnerText;
// this throws NullReferenceException when the type is LinkedList,
// because this is explicitly implemented in LinkedList
collectionType.GetMethod("Add")
.Invoke(collection, new[] { value });
}
return collection;
}
Я пишу небольшую структуру для отображения из объекта в xml, используя атрибуты класса и свойства.Поэтому я не могу использовать универсальные шаблоны, потому что все это делается во время выполнения.
Я изначально проверял IEnumerable
раньше, но столкнулся с другими странностями с ним (строки реализуют IEnumberable
и являются неизменяемыми), которые ярешил, что безопаснее всего придерживаться ICollection<>