Narase
Narase

Reputation: 490

Converting object (List<string>) to List<object>

Im trying to write a small framework for REST-API testing. Im using a lot of reflection and came to a problem I cant help myself.

Im using this line to extract a variable the user gives my as a path (string)

object o = input.GetType().GetProperty(name).propertyInfo.GetValue(input, null);

This object can be a normal type T or a List<T>. Now if its a List and I know the type everything is simple, I can use

List<string> l = (List<string>)o; // I know its a List<string> because the user told me

To parse the object into the given array. But I dont always know the type of the objects in the list and

List<object> l = (List<object>)o; // I dont know the type and I dont care

gives me an error.

Object of type "System.Collection.GenericList[System.String]" can not be converted to "System.Collection.GenericList[System.Object]"

Is there anything I can do to receive the list of objects? I dont want the user to specify the type because its only the last variable I want to care about. Like

The user wants to test "object1.a.b.c" I only need to know the type of c, because thats where the test runs.

TIA

Upvotes: 2

Views: 605

Answers (2)

Avin Kavish
Avin Kavish

Reputation: 8947

Since your problem begins at processing dynamic objects that arrive as JSON to the server, it's quite convenient to use the JSON Processing library itself to test for certain characteristics before converting to POCOs. Using newtonsoft's JSON.Net,

var o = JObject.Parse(json);
JToken property = o["a"]["b"]["c"];
if (property != null)
{
    if (property.Type == JTokenType.Array)
    {
      // Process property as array

    }
    else if  (property.Type == JTokenType.Object)
    {
      // Process property as object
    }
    // Magnitude of other types
}

I do understand the need to convert to .NET types before final processing but I would highly recommend beginning with JObjects as the library is designed for this purpose and provides numerous convenience methods for many dynamic operations that C# doesn't provide natively.

Upvotes: 1

Eric Lippert
Eric Lippert

Reputation: 660058

You may convert it to IEnumerable<object>, but not List<object>. The reason is: a list of bananas is not a list of fruit because you can put an apple into a list of fruit, but not into a list of bananas. Since the two types allow different operations, they are not compatible.

A sequence has no "put into" operation, so it is possible to use a list of bananas as a sequence of fruit. Similarly, you can use a list of strings as a sequence of objects, but not a list of objects.

This feature is called generic covariance; for more information, do a search on C# covariance and you'll find plenty of articles explaining how it works.

Note in particular that covariance only works on reference types; you may not use a sequence of integers as a sequence of objects. Do you see why?

Alternatively, if you have an IEnumerable in hand, you can make a copy of any sequence into a list of objects with mysequence.Cast<object>().ToList(). But this is a copy, not a reference conversion.

Upvotes: 7

Related Questions