【问题标题】:How to instantiate generic classes如何实例化泛型类
【发布时间】:2019-12-12 23:52:12
【问题描述】:

我有一个界面:

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'。 存在显式转换(您是否缺少演员表?)

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

【问题讨论】:

  • 用 ICrawlService 定义你的接口,然后你可以分配给定类型的派生类,所以对于你从 SocialPostBase 派生的类型。
  • WHen 这样做我的存储库失败:无效的方差:类型参数 'T' 必须在 'ISocialRepository 上始终有效
  • 比把“out”也放在那里。当然,他们必须适合。另一种选择是使用 Crawl 并使接口非泛型。

标签: c# generics


【解决方案1】:

这不可能吗?

不,这是可能的。您只需在ICrawlService 中的泛型参数之前添加out

public interface ICrawlService<out T> where T : SocialPostBase

Covariance and Contravariance in Generics

【讨论】:

    【解决方案2】:

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

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

    只要CrawlYoutubeProfileServiceCrawlAnotherProfileService 具有实现SocialPostBase 的类型参数,这应该可以工作,如下所示:

    class YoutubePost : SocialPostBase
    {
    
    }
    
    class CrawlYoutubeProfileService : ICrawlService<YoutubePost>
    {
    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-10-03
      • 2011-04-02
      • 1970-01-01
      • 2013-09-18
      • 1970-01-01
      相关资源
      最近更新 更多