Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert List<T> to List<object>

Tags:

c#

I have a problem with the generic class. I have something like this:

public abstract class IGroup<T> : IEnumerable where T : class {

    protected List<T> groupMembers;
    protected List<IGameAction> groupIGameActionList;

    public IGroup() {
        groupMembers = new List<T>();

        groupIGameActionList = new List<IGameAction>();
        //groupIGameActionList.Add(new DieGameAction(groupMembers));
    }
}

And second class:

class DieGameAction : IGameAction {

    List<object> gameObjectList;

    public DieGameAction(List<object> objectList) {
        gameObjectList = objectList; 
    }
}

I don't know how to cast or convert groupMembers in commented line. This doesn't work because it can not be converted (List<T> to List<object>). So how can I do it?

like image 469
wolen Avatar asked May 24 '13 18:05

wolen


People also ask

Can we convert list string to list object?

The constructor takes a Collection , but List is a subinterface of Collection , so you can just use the List<String> . This constructs unnecessary objects and can, if this is a big list, potentially take up a lot of memory. Just cast it.

How do you convert a generic list?

Select(x => new TestClass() { AAA = (string)x[0], BBB = (string)x[1], CCC = (string)x[2] }). ToList();

How do you use convert all?

ConvertAll(TInput[], Converter<TInput, TOutput>) Method is used to convert an array of one type to an array of another type. Syntax: public static TOutput[] ConvertAll<TInput,TOutput> (TInput[] array, Converter<TInput,TOutput> converter); Here, TInput and TOutput is the source array and target array respectively.


3 Answers

groupMembers.Cast<object>().ToList();

But that doesn't look a good thing to do. You are creating a new empty list that will not be related to the original anymore.

The way you're gonna be using these classes will tell if that would be a good idea. If you're planning to have both lists updated by adding items to a single class, it will not fit. Then maybe your DieGameAction should be generic as well: DieGameAction<T>. Then you could give the original list without casting.

But, there's another danger: if you set a new list to the IGroup, it will not be reflected to DieGameAction.

So, it all depends on what you're trying to do.

like image 61
Daniel Möller Avatar answered Sep 30 '22 17:09

Daniel Möller


I'm going to focus only on providing a solution. You can make DieGameAction use IList < object > instead:

class DieGameAction : IGameAction {

    IList<object> gameObjectList;

    public DieGameAction(IList<object> objectList) {
        gameObjectList = objectList; 
    }
}

Then you can provide an IList < object > implementation which adapts any IList < T >.

public abstract class IGroup<T> : IEnumerable where T : class {

    protected List<T> groupMembers;
    protected List<IGameAction> groupIGameActionList;

    public IGroup() {
        groupMembers = new List<T>();

        groupIGameActionList = new List<IGameAction>();
        groupIGameActionList.Add(new DieGameAction(new ObjectListAdapter<T>(groupMembers)));
    }
}

I'm going to try and provide one of the many possible solutions using as base the System.Collections.ObjectModel.Collection < T > which can also wrap an IList < T >:

public class ObjectListAdapter<T> : System.Collections.ObjectModel.Collection<T>, IList<object>
{
    public ObjectListAdapter(IList<T> wrappedList)
        : base(wrappedList)
    {
    }

    public int IndexOf(object item)
    {
        return base.IndexOf((T)item);
    }

    public void Insert(int index, object item)
    {
        base.Insert(index, (T)item);
    }

    public new object this[int index]
    {
        get
        {
            return base[index];
        }
        set
        {
            base[index] = (T)value;
        }
    }

    public void Add(object item)
    {
        base.Add((T)item);
    }

    public bool Contains(object item)
    {
        return base.Contains((T)item);
    }

    public void CopyTo(object[] array, int arrayIndex)
    {
        this.Cast<object>().ToArray().CopyTo(array, arrayIndex);
    }

    public bool IsReadOnly
    {
        get { return false; }
    }

    public bool Remove(object item)
    {
        return base.Remove((T)item);
    }

    public new IEnumerator<object> GetEnumerator()
    {
        return this.Cast<object>().GetEnumerator();
    }
}

The list changes will throw a type casting exception upon trying to use an unsupported object, the way I programmed it over here, but you can also handle that as you like.

Now, for IList < object > you could also try using IList instead which is also implemented by List < T > so you'll basically have to do nothing more to get this working.

Note that the important thing is that the list will appear the same at both places used since they will basically be using the same underlying List object.

Let me know if this answers your question, by marking it as an answer, or not to refrain :)

like image 28
Demetris Leptos Avatar answered Sep 26 '22 17:09

Demetris Leptos


I just faced the same problem which led me here. The solution that worked for me was to cast into IEnumerable of Object instead of List of Object

(System.Collections.Generic.IEnumerable<object>)groupMembers;
like image 1
Michael Bahig Avatar answered Sep 27 '22 17:09

Michael Bahig