0

I'm parsing a JSON string using MiniJson in Unity. Now I have a value that's a list of strings. Though I get this an object. The underlying type of the object is a List<object>, but actually it should be a List<string>. So currently I do this:

void SetInfo(Dictionary<string,object> info) {
    Colors = (info["colors"] as List<object>).OfType<string>().ToList();
}

The dictionary is what I get from the MiniJson library. This works perfectly. Though seems a bit ugly, a lot of unnecessary casting, and I was wondering if there's a better way of doing this. Mostly I'm looking for cleaner code, and faster execution, since there are a lot of these entries.

Edit: I wasn't very clear about this. In the info dictionary there are a bunch of key/value pairs, the type of the values vary. I can cast most very easily, but the info["colors"] object is the one I'm having problems with.

So when I do info["colors"] I get an object, with an underlying type List<object>. The objects in this list are actually strings.

Also, there's not really a performance problem here, since it's only called once at the start of the program, though there is a noticeable lag currently, I'm going to put it on it's own thread anyway so no problem there. The faster execution is just out of curiosity.

5
  • did you measure the performance and confirmed that there is a performance problem? Commented Apr 16, 2014 at 9:29
  • 3
    "The underlying type of the object is a List, but actually it should be a List" you mean dictionary? Commented Apr 16, 2014 at 9:29
  • Why is it not sent in as Dictionary<string, List<string>>? Commented Apr 16, 2014 at 9:31
  • @Weyland, I mean the underlying type of the object I get when I do info["colors"]. @Magnus, there are other values in it aswell. For instance the info["cmc"] is an int. Commented Apr 16, 2014 at 9:34
  • I edited my question. I'm only just awake, and my question suffered for it. Should be more clear now I hope. Commented Apr 16, 2014 at 9:39

3 Answers 3

4

Try this one.

(info["colors"] as List<object>).ConvertAll(input => input.ToString());

you can also use direct cast (string)input or input as string which is even faster(there were debates on casting here at stackoverflow).

info["colors"] as List<object> can result in null, so I'd rather be more safe and wrap your code like this:

List<object> colors = info["colors"] as List<object>;
List<string> typedColors = null;
if (colors!=null)
{
   typedColors = colors.ConvertAll(input => input as string);
}
Sign up to request clarification or add additional context in comments.

3 Comments

This is a good solution. Though almost the same. Is there a reason why ConvertAll is preferred over my .OfType<string>().ToList(); Other than being only one call?
OfType is an extension method and is not a conversion method, it only returns elements that are already of the specified type, and it will be of type IEnumerable<T>. Meanwhile ConvertAll is not an extension method - it's native method of List class. You don't have to convert IEnumerable to List and you can convert every element like you need.
I think you can also use colors.Cast<string>() safely if you are sure about all items been of type string.
0

Have you thought about using the in and out keywords

3 Comments

For this problem not, what do you propose?
Lists(as they are classes) cannot be variant. You can define custom contravariant interface ICustomList<in T> to make something like ICustomList<string> = ICustomList<object>. But why should you do that, it will cast implicitly anyways.
ah, I think I have misunderstood how the in and out keywords work then. I have never used them but came across the pages I linked to in my comment and thought they might be helpful. Ah well, sorry!
0

I know this code is a bit old school, but we all know what it means:

    List<object> l = new List<object>();
    List<string> s = new List<string>();
    foreach( var i in l )
        s.Add((string)i);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.