[英]Generic interfaces and inheritance in .NET
我有以下场景,涉及如下几个接口
internal interface ITranslation
{
string LanguageCode { get; set; }
string Title { get; set; }
}
任何保存翻译的 object 都将实现ITranslation
接口。 其中一些对象也可以有同义词,所以我有另一个接口
internal interface ITranslationWithSynonmys : ITranslation
{
IList<string> Synonyms { get; set; }
}
下一步,我为任何具有翻译且可以翻译成不同语言的 object 定义了ITranslatable<T>
接口
internal interface ITranslatable<T> where T : ITranslation
{
IList<T> Translations { get; set; }
}
而当涉及同义词时, ITranslatableWithSynonyms<T>
看起来像这样
internal interface ITranslatableWithSynonyms<T> : ITranslatable<T> where T : ITranslationWithSynonmys
{
IList<T> SynonymTanslations { get; set; }
}
ITranslation
和ITranslationWithSynonmys
的具体实现是
internal class BaseTranslation : ITranslation
{
public string Title { get; set; }
public string LanguageCode { get; set; }
}
internal class BaseTranslationWithSynonmys : ITranslationWithSynonmys
{
public IList<string> Synonyms { get; set; }
public string LanguageCode { get; set; }
public string Title { get; set; }
}
而可以翻译的实体将是
internal class TranslatableEntity : ITranslatable<ITranslation>
{
public IList<ITranslation> Translations { get; set; }
}
如果它有同义词
internal class TranslatableWithSynonymsEntity : ITranslatableWithSynonyms<ITranslationWithSynonmys>
{
public IList<ITranslationWithSynonmys> SynonymTanslations { get; set; }
public IList<ITranslationWithSynonmys> Translations { get; set; }
}
接下来,我正在创建一个可以翻译任何实现ITranslatable<T>
的 object 的服务,我将其定义为
internal class TranslationService
{
internal string Translate(ITranslatable<ITranslation> translatable, string languageCode)
{
// It will iterate through the Translations list to find the correct translation
return string.Empty;
}
}
现在,当我尝试使用该服务时,我正在写
var translationService = new TranslationService();
var translatableEntity = new TranslatableEntity();
var translatableWithSynonymsEntity = new TranslatableWithSynonymsEntity();
string x = translationService.Translate(translatableEntity, "en");
string y = translationService.Translate(translatableWithSynonymsEntity, "en");
这里最后一行translationService.Translate(translatableWithSynonymsEntity, "en")
无法编译并出现错误 CS1503: Argument 1: cannot convert from 'TestInheritance.TranslatableWithSynonymsEntity' to 'TestInheritance.ITranslatable<TestInheritance.ITranslation>'
TranslatableWithSynonymsEntity
确实没有实现ITranslatable<ITranslation>
,但它实现了ITranslatableWithSynonyms<ITranslationWithSynonmys>
,其中ITranslatableWithSynonyms<T>
继承自ITranslatable<T>
, ITranslationWithSynonmys
继承自ITranslation
。
我可以通过让TranslatableWithSynonymsEntity
同时实现ITranslatableWithSynonyms<ITranslationWithSynonmys>
和ITranslatable<ITranslation>
来编译代码,但这意味着要管理两个列表并且看起来不干净。
internal class TranslatableWithSynonymsEntity : ITranslatableWithSynonyms<ITranslationWithSynonmys>, ITranslatable<ITranslation>
{
public IList<ITranslationWithSynonmys> SynonymTanslations { get; set; }
public IList<ITranslationWithSynonmys> Translations { get; set; }
IList<ITranslation> ITranslatable<ITranslation>.Translations { get; set; }
}
有没有办法避免这种情况? 还是我采取了错误的方法?
谢谢
默认情况下,泛型参数是不变的,在方法Translate
中,您希望类型为<ITranslation>
,因此您必须提供一个类型,其(或其父代)泛型参数恰好为<ITranslation>
。
在您的示例中,您不能简单地将参数标记为协变,因为它包含一个同时具有 getter 和 setter 的属性。
既然问题是泛型参数,解决问题,不指定一个,其实你已经约束了泛型参数。
interface ITranslatable<T> where T : ITranslation
方法(或类)只需要用相同的约束声明。
internal string Translate<T>(ITranslatable<T> translatable, string languageCode)
where T : ITranslation
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.