Использование дженериков в абстрактных классах - PullRequest
20 голосов
/ 02 марта 2010

Я работаю над абстрактным классом, в котором реализующий класс должен реализовать список T. Проблема в том, что это не работает:

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; }
}

Я уверен, что есть очевидный ответ, который мне не хватает, и я знаю, что могу создать абстрактный базовый тип для добавления в список, но когда я использую команду Linq для построения списка, абстрактный Тип (ItemBase) не очень хорошо работает с методом .ToList (). Что я пытаюсь сделать таким уникальным?

Ответы [ 7 ]

31 голосов
/ 02 марта 2010

Вам также нужно объявление для класса, чтобы знать, что тип T:

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 List<Widgets> Items { get; set; }
}

Вы также можете ограничить, каким может быть T, например, сказать, что он должен реализовывать IWidgets:

public class AbstractClass<T> where T : IWidgets
9 голосов
/ 02 марта 2010
  • Вам необходимо объявить тип T.
  • Вам необходимо объявить класс AbstractClass как абстрактный.
  • Вам необходимо использовать ключевое слово override.

Попробуйте это:

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; }
}
5 голосов
/ 02 марта 2010

Вам нужно сделать AbstractClass универсальный

public class AbstractClass<T> {
  ...
}

public class Container : AbstractClass<Widgets> { ...
}
3 голосов
/ 02 марта 2010
  1. Вам необходимо пометить AbstractClass abstract, поскольку оно содержит абстрактное свойство

  2. Укажите универсальный тип в объявлении AbstractClass

  3. Реализация абстрактного свойства с 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 голосов
/ 02 марта 2010

Вам нужно определить T так, как надо

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; }
}
1 голос
/ 02 марта 2010

Вам необходимо указать тип в абстрактном классе:

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; }
}
0 голосов
/ 11 января 2018

Вам не хватает определения абстрактного ключевого слова для вашего класса AbstractClass, а также вам необходимо добавить ключевое слово override для свойства Items класса контейнера. Я даю пример кода, который будет работать наверняка.

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();
    }
}
}
...