Хобрук: Ваш путь к мастерству в программировании

Как переопределить функцию, которая возвращает список универсальных объектов, расширяющих базовый класс определенным объектом

У меня есть базовый класс (Компания), и я хочу получить от него несколько классов (скажем, CompanyA, CompanyB и т. д.).

Этот базовый класс имеет абстрактный метод, поэтому все производные классы должны переопределять и реализовывать его.

Загвоздка в том, что этот абстрактный метод должен возвращать список любых объектов, производных от данного класса (скажем, CustomerContact).

Я попытался определить этот метод в базовом классе следующим образом:

public class Company
{
    ...
    public abstract List<T> getContacts<T>() where T : CustomerContact;
}

Это не дает ошибки компиляции. Я пытаюсь переопределить этот метод в производном классе следующим образом:

public class CompanyA : Company
{
    ...
    public override List<T> getContacts<T>()
    {
        return _contacts;
    }
}

Здесь _contacts — это список класса «CompanyAContact», где этот класс является производным от «CustomerContact».

Однако я не могу переопределить такой метод. Ошибка, которую я получаю:

Cannot implicitly convert type 'System.Collections.Generic.List<CompanyAContact>' to 'System.Collections.Generic.List<T>'
30.07.2014

Ответы:


1

Ваш метод в производном классе определен как универсальный, но возвращает конкретный список CompanyAContact — что произойдет, если вы вызовете метод, например, так?:

CompanyA companyA = new CompanyA();
//we can't do this as the method returns List<CompanyAContact>
//but we would be asking it for List<CompanyBContact>
companyA.getContacts<CompanyBContact>();

Поскольку это не имеет никакого смысла, вы получаете сообщение об ошибке, что вы не можете преобразовать List<CompanyAContact> в List<T>. Вы не можете вернуть List<CompanyAContact>, если метод определен таким образом, что он может возвращать любой CompanyContact.

Одним из решений было бы сделать базовый класс Company сам универсальным и определить тип CompanyContact, когда вы наследуете Company:

abstract class BaseCompany<T> where T : CustomerContact
{
    //When we inherit from BaseCompany we can define T
    public abstract List<T> getContacts();
}

//define T in this case as CompanyACustomerContact
class CompanyA : BaseCompany<CompanyACustomerContact> 
{
    public override List<CompanyACustomerContact> getContacts() 
    {
        return new List<CompanyACustomerContact>();
    }
}    

//define T in this case as CompanyBCustomerContact
class CompanyB : BaseCompany<CompanyBCustomerContact>
{
    public override List<CompanyBCustomerContact> getContacts()
    {
        return new List<CompanyBCustomerContact>();
    }
}
30.07.2014

2

У меня нет Visual Studio передо мной, чтобы проверить, но я подозреваю, что вам также нужно добавить здесь ограничение типа, чтобы показать, что этот метод совместим с абстрактным методом:

public class CompanyA : Company
{
    ...
    public override List<T> getContacts<T>() where T : CustomerContact;
    {
        return _contacts;
    }
}
30.07.2014

3

Вы можете вернуть список класса CustomerContact, а затем вывести из него определенные классы, такие как мобильный телефон, электронная почта...

30.07.2014

4

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

public class CustomerContact
{
    // ...
}
public class CompanyAContact : CustomerContact
{
    // ...
}

public abstract class Company<T> where T : CustomerContact
{
    // ...
    public abstract List<T> GetContacts();
}
public class CompanyA : Company<CompanyAContact>
{
    private List<CompanyAContact> _contacts; 
    // ...
    public override List<CompanyAContact> GetContacts()
    {
        return _contacts;
    }
}
30.07.2014
Новые материалы

Управление DOM для чайников вроде меня
Одной из первых вещей, которую мы рассмотрели, когда начали изучать Javascript во Flatiron, была модель DOM. Кто он? Чем он занимается? Он больше машина, чем человек? Ну да довольно много. ДОМ..

Что такое структура данных?
Структура данных хранит и извлекает данные. Все, что обеспечивает эти две функции, является структурой данных . Период. Вы можете пропустить оставшуюся часть статьи, если ответ..

мои январские чтения по программированию
Эрик Эллиот Программирование приложения JavaScript Эл Свейгарт «Автоматизируйте скучные вещи с помощью Python» Прогрессивное веб-приложение Google..

Создание ассоциаций секвелизации с помощью инструмента командной строки Sequelize
Sequelize - популярный, простой в использовании инструмент объектно-реляционного сопоставления (ORM) JavaScript, который работает с базами данных SQL. Довольно просто начать новый проект с..

Искусственный интеллект в юридической отрасли - пример прогнозирования судебных решений с помощью глубокого обучения
На протяжении всей истории люди полагались на суды, присяжных, королей и королев в отправлении правосудия. Сегодня способность судов обеспечивать справедливое и быстрое правосудие для своих..

Введение в машинное обучение для обнаружения аномалий (часть 1)
Тщательно созданный, тщательно спроектированный ресурс для специалистов по данным. Часть 1 Главы 03 из Руководства по машинному обучению для обнаружения аномалий Внимание! Прежде чем вы..

Начало работы с Pulumi в Digital Ocean
Цифровой океан (ДО) — отличная альтернатива многим другим поставщикам облачных услуг. DO предоставляет простой и понятный пользовательский интерфейс, упрощающий управление инфраструктурой и..