【问题标题】:How do I create instance of class implementing generic interface with base type如何使用基类型创建实现泛型接口的类的实例
【发布时间】:2014-12-11 08:15:31
【问题描述】:

假设我有这个:

public class BaseEntity {}

public class Product : BaseEntity {}

public interface IPreLoad<T> where T : BaseEntity 
{
    void Preload();
}

public class ProductService : IPreload<Product> 
{
    public void Preload()
    {
        //Do something
    }
}

//Returns list of types implementing IPreload<>
var preloaders = typeFinder.FindClassesOfType(typeof(IPreLoad<>)).ToList(); 

foreach (var preloaderType in preloaders)
{
    var preloader = (IPreLoad<BaseEntity>)EngineContext.Current.ResolveUnregistered(preloaderType);
    cacheManager.Get(preloader.PreLoadCacheKey, () => preloader.PreLoad());
}

我遇到的问题是我无法将ProductService : IPreLoad&lt;Product&gt; 转换为IPreLoad&lt;BaseEntity&gt;,而且我不知道如何才能实现相同的结果。基本上,我想创建这个服务的一个实例并调用 preload。

不执行转换工作正常,它会创建一个实例,但由于我没有将它转换为任何东西,我无法根据接口对其进行任何调用。

【问题讨论】:

    标签: c# reflection interface


    【解决方案1】:

    你的界面应该是协变的:

    public interface IPreLoad<out T> where T : BaseEntity 
    {
        void Preload();
    }
    

    那么,分配就OK了:

    IPreLoad<BaseEntity> preLoader = new ProductService();
    

    【讨论】:

    • 啊,这就是当 resharper 说要更改为协变时的意思 :) 太好了,非常感谢。
    • @webnoob 完全正确 :) 更多关于msdn.microsoft.com/en-us/library/vstudio/…
    • 谢谢你,正要搜索参考文件来阅读它们。它几乎描述了我的确切情况^^
    【解决方案2】:

    在您的示例中,预加载方法不受泛型类型 T 的影响,您可以使用非泛型接口,如

    public interface IPreLoad
    {
        void Preload();
    }
    
    public interface IPreLoad<T>: IPreload where T : BaseEntity 
    {
       // your other typed methods...
    }
    

    然后您将对象转换为 IPreload 而不是 IPreLoad&lt;BaseEntity&gt;

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-25
      • 1970-01-01
      相关资源
      最近更新 更多