简体   繁体   中英

Interface with a list of interface, how to choose one type implemented by interface

This is my first question on StackOverflow, so please forgive and tell me if I'm doing something wrong.

Problem:

I write some kind of dictionary connected to DB and text files etc. nothing commercial, just learning. For better explanation it can be English-French.

I want to refactor the code to have possibility of use one "general" method to process entrance for English-French and French-English dictionary model. On the begining i made separate model for each of them(I will paste if necessary) and now i would like to make everything "universal". What I did till i stop:

public interface IWordModel 
{

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

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

Interface implementing IWordModel and problematic List of this interface:

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

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

And my Question

  1. How to make that ie in FrenchDictionairyModel instance we will be able to define BaseWord only as FrenchWordModel and add to DerivativeWords list ONLY EnglishWordModel? I know it have something common with covariance and contrvariance but i dont have idea how to apply this here.

  2. Is it above code have some sense from experienced coder point of view or it's look like OK only in my head? If answer is NO then how it should look like, what pattern should i use?

  3. How to use it properly in other methods? As now i was using ie

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

    ( ... )}

    but its already showing "Using generic type requires 1 type arguments".

Thanks and have a Great Day!

It sounds like you need two generic parameters - one to apply to BaseWord and one to apply to DerivativeWords :

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

Then define your FrenchDictionaryModel as so:

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

Thanks D Stanley! it works fine, just need to add two where clauses for U and T like:

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

But now i have another issue which i would like to implement here. For example i would like to create some method which will be remove duplicates from List but i want to this to be ONE method for all class which implementing IDictionairyModel

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

What I need to do to be able to use this extension method on

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

As for now it return error. Should I make FrenchDictionairyModel also generic like:

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

??? What is the proper way

Thanks a lot!!!

Have a wonderful Sunday!

Best Regards

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM