简体   繁体   中英

RunTime exception on Convert.ChangeType with List<>

I am running into a RunTime Exception while trying to run a List (cast as object) through Convert.ChangeType. This is basically the setup:

using System;
using System.Collections.Generic;

public class Program
{
    public static void Main()
    {
        List<string> list = new List<string>{ "1", "2", "3"};
        Utils utils = new Utils();
        utils.ChangeType(list, typeof(List<int>));
        Console.WriteLine("Done!");
    }
}

public class Utils
{
    public object ChangeType(object obj, Type type)
    {
         return Convert.ChangeType(obj, type);
    }
}

Fiddle here .

This generates the following exception:

Run-time exception (line 19): Object must implement IConvertible.

Stack Trace:

    [System.InvalidCastException: Object must implement IConvertible.]
       at System.Convert.ChangeType(Object value, Type conversionType, IFormatProvider provider)
       at System.Convert.ChangeType(Object value, Type conversionType)
       at Utils.ChangeType(Object obj, Type type) :line 19
       at Program.Main() :line 10

I have no clue how to fix this. I think I should cast object obj in Utils.ChangeType to a list of a generic type if it is a list, but I cannot get that to work.

Does anyone know how to fix this issue?

I fixed the issue by adding the following check to Utils.ChangeType:

if (IsList(obj))
{
    List<object> objs = ((IEnumerable)obj).Cast<object>().ToList();
    Type containedType = type.GenericTypeArguments.First();
    return objs.Select(item => Convert.ChangeType(item, containedType)).ToList();
}

With IsList being a generic function in Utils to check if object is a List<>.

See the updated fiddle .

As the exception states, the object you are trying to use convert on does not implement IConvertible. You are trying to convert a list of strings to a list of ints, and the list type is not implementing the required interface.

String and int types do implement this interface, so you can do it like this:

  List<string> list = new List<string> { "1", "2", "3" };
  Utils utils = new Utils();
  var result = list.Select(o => (int)Convert.ChangeType(o, typeof(int)));
  Console.WriteLine("Done!");

Or more concisely:

  List<string> list = new List<string> { "1", "2", "3" };
  Utils utils = new Utils();
  var result = list.Select(Int32.Parse);
  Console.WriteLine("Done!");

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM