[英]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.