Reputation: 545
I have written a method which is
public List<List<object>> Fetch(string data)
,
inside I create
List<List<object>> p = new List<List<object>>();
my boss now wants to return a IList<IList<object>>
instead of List<List<object>>
ie
public IList<IList<object>> Fetch(string data)
,
so when I try do
return (IList<IList<object>>) p; //throws an exception
How do I convert
List<List<object>>
to IList<IList<object>>
and back to List<List<object>>
Upvotes: 51
Views: 78799
Reputation: 112762
You would have to declare your list as
IList<IList<object>> list = new List<IList<object>>(); // Works!
This works, because only the outer list is created in the first place. You can then insert individual items that are compatible with IList<object>
:
list.Add(new List<object>());
list.Add(new object[10]);
Upvotes: 14
Reputation: 81700
List<T>
and IList<T>
do not support covariance. So this does not compile:
List<List<string>> list = new List<IList<string>>(); // DOES NOT COMPILE!!!!!
Upvotes: 0
Reputation: 35146
You need to change the declaration of the result variable from List<List<object>
to IList<IList<object>>
Which you can instantiate against List<IList<object>>
And each item in the result can be of type List<object>
static IList<IList<object>> Test()
{
IList<IList<object>> result = new List<IList<object>>();
var item = new List<object>() { "one", "two", "three" };
result.Add(item);
return result;
}
Upvotes: 2
Reputation: 1503439
You can't perform that conversion via straight casting - it wouldn't be safe. Instead, you should use:
IList<IList<object>> ret = new List<IList<object>>();
Then for each "sublist" you can use:
// Or whatever
ret.Add(new List<object>());
Finally, just return ret
.
You could use LINQ to perform the conversion of your existing List<List<object>>
when you return it - but it would be better to just create a more appropriate type to start with, as shown above.
To understand why some of the existing answers are wrong, suppose you could do this:
IList<IList<object>> p = new List<List<object>>();
Then this would be valid:
List<List<object>> listOfLists = new List<List<object>>();
IList<IList<object>> p = listOfLists;
p.Add(new object[]);
List<object> list = p[0];
But p[0]
is a reference to an object[]
, not a List<object>
... our supposedly type-safe code doesn't look as safe any more...
Fortunately, IList<T>
is invariant to prevent exactly this problem.
Upvotes: 98
Reputation: 2391
public IList<IList<object>> Fetch(string data)
{
IList<IList<object>> p = new List<IList<object>>();
// add your stuff here
return p;
}
Upvotes: 1
Reputation: 51369
var myOriginalList = new List<List<Object>>();
var converted = ((IList<IList<Object>>)myOriginalList.Cast<IList<Object>>().ToList()); // EDIT: Added .ToList() here
You shouldn't need to convert back- you can do just about anything on IList
that you could on List
.
Upvotes: 5