2

I am trying to create a class that will edit Lists of objects. Its constructor accepts any list of object that implements the 'INameable' interface. It's method can then add one more member to the list.

For Example:

public static class Data
{
    //All of these object types implement the INameable interface
    List<Apple> Apples = new List<Apple>();
    List<Orange> Oranges = new List<Orange>();
    List<Pear> Pears = new List<Pear>();
}

public class ListEditor
{
    private List<INameable> _list;
    private Type _type;
    public  ListEditor(List<INameable> l, Type t)
    {
        _list = l;
        _type = t
    }

    public void AddMember()
    {
        var newObject Activator.CreateInstance(_type);
        _list.Add((iNameable)newObject );
    }
}

Program
{
    //these lines are not working because the casting is invalid...
    private ListEditor _appleEditor = new ListEditor((List<INameable>)Data.Apples, TypeOf(Apple));
    private ListEditor _orangeEditor = new ListEditor((List<INameable>)Data.Oranges, TypeOf(Orange));
    private ListEditor _pearEditor = new ListEditor((List<INameable>)Data.Pears, TypeOf(Pear));
}

Problems:

What is the correct syntax to cast List as List WITHOUT creating a new list (which would break the reference to the original list)

  • 1
    `List` is not covariant as it would not be safe (see [this question](http://stackoverflow.com/questions/2033912/c-sharp-variance-problem-assigning-listderived-as-listbase)), so what you're trying to do isn't possible. You could cast to the non-generic `IList` instead, but Grant's answer seems to be a better answer - what is the problem with this? – Charles Mager Jul 10 '15 at 07:06

1 Answers1

1

Sounds like you could just extend List<T> and add the new method you need to your class:

public class ListEditor<T> : List<T> where T : new()
{
    public void AddMember()
    {
        Add(new T());
    }
}

Use it like this:

var _appleEditor = new ListEditor<Apple>();

_appleEditor.AddMember();

var _orangeEditor = new ListEditor<Orange>();

_orangeEditor.AddMember();

Or, if you really just wanted a class that could hold a reference to your original list, and have a method that adds new items to it:

public class ListEditor<T> where T : new()
{
    private readonly List<T> originalList;

    public ListEditor(List<T> list)
    {
        originalList = list;
    }

    public void AddMember()
    {
        originalList.Add(new T());
    }
}

var originalApples = new List<Apple>();

var newApples = new ListEditor<Apple>(originalApples);
newApples.AddMember();
Grant Winney
  • 65,241
  • 13
  • 115
  • 165
  • I'm smelling a best answer here. I'm going to try that. #MindBlown – Lorry Laurence mcLarry Jul 10 '15 at 05:06
  • Actually, ListEditor is a windows forms custom control. I will still need to pass it lists. I just like your idea to extend List to include an 'AddMember' method because it would obviously know its own type. Let's call this 'UltraList'. So in 'Data' I would have 'UltraList Apples' etc. But if we recast it to Ultralist and then used .AddMember() would it still remeber that its type is Apples? Or would it think that it is trying to add use type INameable? – Lorry Laurence mcLarry Jul 10 '15 at 05:31
  • oh... I just realised that extending List still doesn't solve the list casting problem... – Lorry Laurence mcLarry Jul 10 '15 at 05:40