如何实例化泛型类

时间:2019-12-12 15:04:19

标签: c# generics

我有一个界面:

public interface ICrawlService<T> where T : SocialPostBase
{
    Task<int> Crawl(int accountId, Disguise disguise, ISocialAccountRepository socialAccountRepository, ISocialRepository<T> socialRepository, ISocialCrawlJobRepository jobRepository, IInstrumentationRepository instrumentationRepository);
}

我的社交资源库是:

public interface ISocialRepository<T> where T : class
{
    IEnumerable<SocialPostCollection<T>> List { get; }
    Task Add(SocialPostCollection<T> entity, string type);

    Task AddPosts(List<T> entity, string type);

    void Delete(SocialPostCollection<T> entity);
    void Update(SocialPostCollection<T> entity);
    T Find(string profileName, MediaType type);
}

我正在寻找一种多态设计,因此可以将不同的类实例化为一个类型。像这样:

var socialRepo = new SocialRepository<Video>(configration.CosmosDBServiceEndpoint, configration.CosmosDBSecret, configration.CosmosDBDatabaseId);
var socialRepo2 = new SocialRepository<Post>(configration.CosmosDBServiceEndpoint, configration.CosmosDBSecret, configration.CosmosDBDatabaseId);

ICrawlService<SocialPostBase> crawlService;

crawlService = new CrawlYoutubeProfileService();
var id = await crawlService.Crawl(jobId, null, _socialAccountRepo, socialRepo, _socialCrawlJobRepo, instrumentationRepo);

crawlService = new CrawlAnotherProfileService();
var id2 = await crawlService.Crawl(jobId, null, _socialAccountRepo, socialRepo2, _socialCrawlJobRepo, instrumentationRepo);

但是它将不接受通用参数的基类,但出现以下错误。

  

无法隐式转换类型   'SocialCrawlServices.CrawlYoutubeProfileService'到   “ SocialCrawlServices.ICrawlService”。   存在显式转换(您是否缺少演员表?)

那么您如何进行通用的多态设计?那不可能吗?

2 个答案:

答案 0 :(得分:1)

  

那不可能吗?

不,有可能。您只需在out中的通用参数之前添加ICrawlService

public interface ICrawlService<out T> where T : SocialPostBase

请参见Covariance and Contravariance in Generics

答案 1 :(得分:0)

错误显示“存在显式转换(您是否缺少演员表?)”。答案是将实现类显式转换为接口:

crawlService = (ICrawlService<SocialPostBase>)new CrawlYoutubeProfileService();

crawlService = (ICrawlService<SocialPostBase>)new CrawlAnotherProfileService();

只要CrawlYoutubeProfileServiceCrawlAnotherProfileService具有实现SocialPostBase的类型参数,就可以使用它,如下所示:

class YoutubePost : SocialPostBase
{

}

class CrawlYoutubeProfileService : ICrawlService<YoutubePost>
{

}