Преобразовать.ChangeType (ошибка: объект должен реализовать IConvertible) при сбое динамического преобразования объекта в IList Почему?

#c# #list #dynamic

#c# #Список #динамический

Вопрос:

Я использую этот Convert.ChangeType(object, Type) метод для преобразования объектов в их типы. Это сработало великолепно. Это работает просто отлично, когда я пытаюсь преобразовать an Object (типа List<string> ) обратно в a List<string> . Однако, когда я пытаюсь преобразовать an Object в a IList<string> , это не удается.

Проблема: Когда я пытаюсь преобразовать объект, который должен иметь тип IList , в IList , он завершается с сообщением об ошибке «Объект должен реализовать IConvertible»

 IList<string> myList = new List<string>();
object myObject = myList;
Type myType = typeOf(IList<string>);
Convert.ChangeType(myObject, myType);
 

Кто — нибудь знает, как успешно преобразовать объект обратно в его исходный тип IList … Или кто-нибудь знает, как преобразовать объект, который изначально был IList, в список? И то, и другое сработало бы.

Комментарии:

1. Ваше утверждение » Это работает просто отлично, когда я пытаюсь преобразовать an Object (который ранее был типа List<string> ) обратно в a List<string> указывает на возникшее у вас недопонимание. Если объект является a List<string> , он остается a List<string> , даже если вы сохраняете ссылку на него в переменной типа object . Нет необходимости менять его тип ; тип остается прежним.

2. Это IList, а не список. Здесь нет никакого недоразумения. Боролся с этим слишком долго, чтобы это было недоразумением. В основном публикую это, чтобы другие тоже не сталкивались с этим.

3. Это и ан List<string> , и ан IList<string> . Моя точка зрения не имеет ничего общего с List или IList . Если я создам объект: object o = new List<int>(); . Этот объект — a List<int> , an IList<int> , an object , an IEnumerable и т. Д. Если я сохраню ссылку на этот объект в переменной любого из этих типов ( IEnumerable ie = (IEnumerable)o; ) , это не изменит базовую природу (/ тип) объекта.

4. Хорошо, я понимаю, о чем ты говоришь. Объект никогда не был списком. Возможно, это был лучший способ сформулировать оператор.

Ответ №1:

Приведенный ниже код решил мою проблему:

 // Initial objects (the original IList object ended up as an object plus a Type)
IList<string> stringList = new List<string>(); // dont' have access to this form of the object
object myObject = stringList;
Type originalType = typeof(List<string>);

// Converting object to a List<string>
if(originalType.Name.StartsWith("IList"))
{
  Type myNewList = typeof(List<>);
  Type typeInIList = originalType.GenericTypeArguments[0];
  Type aStringListType = myNewList.MakeGenericType(typeInIList);
  dynamic newStringList = Convert.ChangeType(myObject, aStringListType);
}
 

Ответ №2:

Нет необходимости использовать Convert.ChangeType , или dynamic . Если объект на самом деле является an IList<string> , вы можете использовать шаблон is типа для его проверки:

 if (myObject is IList<string> list) {
    // "list" is the converted list
} else {
    // conversion fails
}
 

Комментарии:

1. Спасибо за ответ. Для того, что я делаю с объектом позже в коде, мне нужно преобразовать его обратно в список.