接口列表接口,如何选择接口实现的一种类型

问题描述 投票:1回答:2

这是我在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个类型参数”。

谢谢,祝你有个美好的一天!

c# generics interface covariance contravariance
2个回答
0
投票

听起来你需要两个通用参数 - 一个适用于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>();
}

0
投票

谢谢D Stanley!它工作正常,只需要为U和T添加两个where子句,如:

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

但现在我有另一个问题,我想在这里实施。例如,我想创建一些方法,将从List中删除重复,但我希望这是实现IDictionairyModel的所有类的ONE方法

        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

???什么是正确的方法

非常感谢!!!

祝周日愉快!

最好的祝福

© www.soinside.com 2019 - 2024. All rights reserved.