Интерфейс со списком интерфейсов, как выбрать один тип, реализованный интерфейсом - PullRequest
0 голосов
/ 01 марта 2019

Это мой первый вопрос по StackOverflow, поэтому, пожалуйста, простите и скажите, что я делаю что-то не так.

Проблема:

Я пишу какой-то словарь, связанный с БД и текстомфайлы и т.д. ничего коммерческого, просто учусь.Для лучшего объяснения это может быть англо-французский.

Я хочу реорганизовать код, чтобы иметь возможность использовать один "общий" метод для обработки ввода для англо-французской и французско-английской модели словаря.В начале я сделал отдельную модель для каждого из них (я буду вставлять при необходимости), и теперь я хотел бы сделать все "универсальным".Что я делал, пока не остановился:

public interface IWordModel 
{

    int Id { get; set; }
    string Name { get; set; }
    string Definition { get; set; }
}

класс, реализующий IWordModel:

public class EnglishWordModel: IWordModel
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Definition { get; set; } = null;
}
public class FrenchWordModel : IWordModel
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Definition { get; set; } = null;
}

Интерфейс, реализующий IWordModel и проблемный Список этого интерфейса:

public interface IDictionairyModel<T> where T : IWordModel
{
    int Id { get; set; }
    T BaseWord { get; set; }
    List<T> DerivativeWords { get; set; }
}

Реализация классаIDicionairyModel

public class EnglishFrenchDictionairyModel<T>: IDictionairyModel where T : IWordModel
{
    public int Id { get; set; }
    public IWordModel BaseWord { get; set; } = new EnglishWordModel();
    public List<IWordModel> DerivativeWords { get; set; } =  = new 
    List<IWordModel>(new List<FrenchWordModel>());
}
public class FrenchDictionairyModel: IDictionairyModel<T> where T : IWordModel
{
    public int Id { get; set; }
    public IWordModel BaseWord { get; set; } = new FrenchWordModel();
    public List<IWordModel> DerivativeWords { get; set; } =  = new 
    List<IWordModel>(new List<EnglishWordModel>());
}

И мой вопрос

  1. Как сделать это, то есть в экземпляре FrenchDictionairyModel мы сможем определить BaseWord только как FrenchWordModel и добавить в список DerivativeWords ТОЛЬКО EnglishWordModel?Я знаю, что это имеет что-то общее с ковариацией и контравариантностью, но я понятия не имею, как применить это здесь.

  2. Это код выше с точки зрения опытного кодера, или это похоже наОК только в моей голове?Если ответ НЕТ, то как он должен выглядеть, какой шаблон мне использовать?

  3. Как правильно использовать его в других методах?Как и сейчас, я использовал, например,

    public List<EnglishFrenchDictionairyModel> 
    CreateEnglishFrenchEntrance(List<EnglishFrenchDictionairyModel> model){     
    

    (...)}

    , но уже показывалось: «Использование универсального типа требует аргументов 1 типа».

Спасибо и хорошего дня!

Ответы [ 2 ]

0 голосов
/ 03 марта 2019

Спасибо, Стэнли!он работает нормально, просто нужно добавить два предложения where для U и T вроде:

public interface IDictionairyModel<T,U> 
where T : IWordModel,
where U : IWordModel {(...)}

Но теперь у меня есть еще одна проблема, которую я хотел бы реализовать здесь.Например, я хотел бы создать некоторый метод, который будет удалять дубликаты из списка, но я хочу, чтобы это был ОДИН метод для всех классов, реализующих IDictionairyModel

        public static List<IDictionairyModel<IWordModel, IWordModel>> RemoveDuplicates(this List<IDictionairyModel<IWordModel, IWordModel>> model)
    {
        (...)  return model;
    }

Что мне нужно сделать, чтобы иметь возможность использоватьэтот метод расширения на

List<FrenchDictionairyModel> model = new List<FrenchDictionairymodel>();
model.RemoveDuplicates();

А пока он возвращает ошибку.Должен ли я сделать FrenchDictionairyModel также универсальным, как:

public class PoznanPolishDictionairyModel<T,U> : IDictionairyModel<PoznanWordModel, PolishWordModel>
where T:IWordModel
where U:IWordModel

???Как правильно

Большое спасибо !!!

Хорошего вам воскресенья!

С наилучшими пожеланиями

0 голосов
/ 01 марта 2019

Похоже, вам нужно два универсальных параметра - один для применения к BaseWord и один для применения к DerivativeWords:

public interface IDictionairyModel<T,U> 
    where T : IWordModel, U : IWordModel
{
    int Id { get; set; }
    T BaseWord { get; set; }
    List<U> DerivativeWords { get; set; }
}

Затем определите свой FrenchDictionaryModel какитак:

public class FrenchDictionairyModel: 
    IDictionairyModel<FrenchWordModel, EnglishWordModel>
{
    public int Id { get; set; }
    public FrenchWordModel BaseWord { get; set; } = new FrenchWordModel();
    public List<EnglishWordModel> DerivativeWords { get; set; } =  new List<EnglishWordModel>();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...