Question How to Cast Object to List<int>

fakeNoose

Member
Joined
Sep 19, 2019
Messages
10
Programming Experience
Beginner
Hey everyone,

I have an API that is converting my List<int> into an object so that it can be sent over the network. When I get it on the receiving end I'm trying to convert it back to a List<int> but I can't figure out how to do that.

When I print the object.ToString() out I see the below:
C#:
System.Collections.Generic.List`1[System.Object]

Any help or guidance on how to do this properly would be greatly appreciated!

C#:
class Identity
{
    private static List<int> _characterlist = new List<int>();

    public static List<int> CharacterList
    {
        get { return _characterlist; }
        protected set { _characterlist = value; }
    }

    private void identitySync(ExpandoObject id)
    {
        _characterlist.Clear();

        Identity player = new Identity();
        foreach (var v in id)
        {
            if (v.Value is IList && v.Value.GetType().IsGenericType)
            {
                // This is where I need to convert to the list
                Console.WriteLine($"{v.Value.ToString()}");
                _characterlist = new List<int>(v.Value);
            }
            else
            {
                PropertyInfo pInfo = player.GetType().GetProperty(v.Key);
                pInfo.SetValue(player, Convert.ChangeType(v.Value, pInfo.PropertyType), null);
            }
        }
    }
}
 
If what you actually have is a List<object> where each item is a boxed int then you're not actually casting that top-level object. You have to create a new List<int> and cast each item in the old list before adding it. There are various ways to do that but, if the reference you have is type IList, this is probably the easiest way:
C#:
_characterList = v.Value.Cast<int>().ToList();
The equivalent long-hand code would be this:
C#:
_characterList = new List<int>();

foreach (var n in v.Value)
{
    _characterList.Add((int)n);
}
 
Is there a possibility that more than one item in id will match the condition in your if statement? If so, you're only going to get the last set of data in _characterList.
 
If what you actually have is a List<object> where each item is a boxed int then you're not actually casting that top-level object. You have to create a new List<int> and cast each item in the old list before adding it. There are various ways to do that but, if the reference you have is type IList, this is probably the easiest way:
C#:
_characterList = v.Value.Cast<int>().ToList();
The equivalent long-hand code would be this:
C#:
_characterList = new List<int>();

foreach (var n in v.Value)
{
    _characterList.Add((int)n);
}

Hey, thanks for the help!

That unfortunately didn't work. Visual studio throws the error: "foreach statement cannot operate on variables of type 'object' because 'object' does not contain a public instance definition for 'GetEnumerator'" I don't understand why it's actually matching that condition in the if.. if it's actually just an object but it is
 
I figured it out, I just needed to cast the object as dynamic. Thank you for your help!!!

C#:
foreach (var n in (dynamic)v.Value)
{
    _characterList.Add((int)n);
}
 
I didn't read the rest of your code carefully enough. I would actually change it a bit like this:
C#:
foreach (var v in id)
{
    var value = v.Value as Ilist;
    
    if (value != null && value.GetType().IsGenericType)
    {
        _characterlist = value.Cast<int>().ToList();
    }
    else
    {
        PropertyInfo pInfo = player.GetType().GetProperty(v.Key);
        pInfo.SetValue(player, Convert.ChangeType(v.Value, pInfo.PropertyType), null);
    }
}
 
The problem with that is every thing that in the object 'id' isn't necessarily a list. I removed all of the non relevant properties from code on here. I'm using Reflections in the else for everything else. Reflections just kept failing for me with lists...
 
The problem with that is every thing that in the object 'id' isn't necessarily a list.
No, that isn't a problem. The as keyword is a conditional cast. This line:
C#:
var value = v.Value as IList;
will result in value referring to an object that implements the IList interface if v.Value refers to one and, otherwise, it will result in value being null, hence the following if statement.
 
And if you use C# 7.0 pattern matching...
C#:
foreach (var v in id)
{
    if (v.Value is IList value && value.GetType().IsGenericType)
    {
        _characterlist = value.Cast<int>().ToList();
    }
    else
    {
        PropertyInfo pInfo = player.GetType().GetProperty(v.Key);
        pInfo.SetValue(player, Convert.ChangeType(v.Value, pInfo.PropertyType), null);
    }
}
 
Back
Top Bottom