27

I'm working on an abstract class where the implementing class needs to implement a list of T. The problem is that this doesn't work:

public class AbstractClass
{
    public int Id { get; set; }
    public int Name { get; set; }

    public abstract List<T> Items { get; set; }
}

public class Container : AbstractClass
{
    public List<Widgets> Items { get; set; }
}

I'm sure that there is an obvious answer that I'm missing, and I know that I can build an abstract base type to put in the list, but when I use my Linq command to build the list, the abstract type (ItemBase) doesn't play nicely with the .ToList() method. Is what I'm trying to do so unique?

thaBadDawg
  • 5,160
  • 6
  • 35
  • 44
  • It turns out that I need to learn to research better. Apologies to all of the answers that were the same that didn't get the check mark. I chose the top one based off of it's completeness and the fact it was top. – thaBadDawg Mar 01 '10 at 22:31
  • Do you actually want `Items` to be abstract? (ie to override the get or set properties?) If you extend from `AbstractClass` like most people are suggesting, `Container.Items` will implicitly be a `List`, and you won't even need to override it. – Tanzelax Mar 01 '10 at 22:39
  • I want to leave the possibility of the getter and setter methods being overridden later on. In theory I don't need to, but in practice trying to undo that mess leads to a world of hurt. – thaBadDawg Mar 01 '10 at 23:15

7 Answers7

45

You need the declaration on the class as well, to know what type T is:

public abstract class AbstractClass<T>
{
    public int Id { get; set; }
    public int Name { get; set; }

    public abstract List<T> Items { get; set; }
}

public class Container : AbstractClass<Widgets>
{
    public override List<Widgets> Items { get; set; }
}

You can also restrict what T can be, like say it must implement IWidgets:

public class AbstractClass<T> where T : IWidgets
Igor
  • 3,573
  • 4
  • 33
  • 55
Nick Craver
  • 623,446
  • 136
  • 1,297
  • 1,155
  • 3
    Don't forget to add the `abstract` key word in the class declaration line itself, not just the property. – Nick Mar 01 '10 at 22:30
11
  • You need to declare the type T.
  • You need to declare the class AbstractClass as abstract.
  • You need to use the override keyword.

Try this:

public class Widgets { }

public abstract class AbstractClass<T>
{
    public int Id { get; set; }
    public int Name { get; set; }

    public abstract List<T> Items { get; set; }
}

public class Container : AbstractClass<Widgets>
{
    public override List<Widgets> Items { get; set; }
}
Mark Byers
  • 811,555
  • 193
  • 1,581
  • 1,452
6

You need to make AbstractClass generic

public class AbstractClass<T> {
  ...
}

public class Container : AbstractClass<Widgets> { ...
}
JaredPar
  • 733,204
  • 149
  • 1,241
  • 1,454
3
  1. You need to mark AbstractClass abstract, because it contains abstract property

  2. Specify the generic type in the AbstractClass declaration

  3. Implement abstract property with override


public abstract class AbstractClass<T>
{
    public int Id { get; set; }
    public int Name { get; set; }

    public abstract List<T> Items { get; set; }
}

public class Container : AbstractClass<Widgets>
{
    public override List<Widgets> Items { get; set; }
}

2

You need to define T like so

public class AbstractClass<T>
{
    public int Id { get; set; }
    public int Name { get; set; }

    public abstract List<T> Items { get; set; }
}

public class Container : AbstractClass<Widget>
{
    public List<Widgets> Items { get; set; }
}
JDMX
  • 1,489
  • 9
  • 22
1

You need to specify the type in the abstract class:

public class AbstractClass<T>
{
    public int Id { get; set; }
    public int Name { get; set; }

    public abstract List<T> Items { get; set; }
}

public class Container : AbstractClass<Widgets>
{
    public List<Widgets> Items { get; set; }
}
Reed Copsey
  • 554,122
  • 78
  • 1,158
  • 1,373
0

You are missing to define abstract keyword for your AbstractClass class and also you need to add override keyword for Container Class Items property. I am giving the example code which will run for sure.

namespace AbstractGeneric
{

public abstract class AbstractClass<T>
{
    public int Id { get; set; }
    public int Name { get; set; }

    public abstract List<T> Items { get; set; }
}

public class Widgets
{
    public int ID { get; set; }
    public string Name { get; set; }
}

public class Container : AbstractClass<Widgets>
{
    public override List<Widgets> Items { get; set; }
    public Container()
    {
        Items = new List<Widgets>();
    }

}


class Program
{
    static void Main(string[] args)
    {
        Container c = new Container();
        c.Items.Add(new Widgets() { ID = 1, Name = "Sample Widget 1" });
        c.Items.Add(new Widgets() { ID = 2, Name = "Sample Widget 2" });

        foreach (Widgets item in c.Items)
        {
            Console.WriteLine(item.ID + " : " + item.Name);
        }

        Console.ReadLine();
    }
}
}