如何将不同的泛型类分配给同一个变量

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何将不同的泛型类分配给同一个变量相关的知识,希望对你有一定的参考价值。

我知道这个问题可能已被多次询问过,我的标题可能需要一些帮助,所以在指出我重复之后随意关闭这个问题...目前还不确定如何正确搜索答案。

我有一个情况,变量可能需要保持和ISolrOperations<Class1>的实例或它可能需要持有ISolrOperations<Class2>的实例。问题是没有接口的基本版本,所以没有类我可以将变量定义为(除了对象,显然不知道ISolrOperations<T>的方法)能够容纳任何一个类。

因此,我所知道的唯一解决方案是:a)执行if / else语句,我在一个块中使用ISolrOperations<Class1>完成所需的一切,在另一个块中使用ISolrOperations<Class2>所需的一切,即使每个块基本上都包含重复的代码。或者b)我可以使变量动态化,只是失去一些编译时验证我的代码。

我正在考虑是否有某种方法可以创建一个具有非泛型基础的通用包装类。也许基地必须把它作为一个对象来对待,但是使用反射...但是我们就像把它当作螺丝一样;如果我必须经历那个麻烦,也可以使用dynamic关键字。

是否有更“适当”的设计模式来处理这种情况?或者我的选择基本上是在动态或编写大量代码之间,只是为了让自己感觉我在做“正确”时动态是最实用的解决方案?

编辑:其实我不确定动态是否会解决这个问题:/

编辑2:没有...其他代码使用lambdas和变量,需要转换它,我显然不知道在编译时要转换什么,所以这将无法工作。

答案

将类包装在实现所需接口的通用适配器类中。

这称为适配器模式,以防您想要搜索它的示例。

通用适配器的示例:

public class SomeGenericInterfaceAdapter<T> : INonGenericInterface
{
    private IGenericInterface<T> _someGenericInterface;
    public SomeGenericInterfaceAdapter(IGenericInterface<T> someGenericInterface)
    {
        _someGenericInterface = someGenericInterface;
    }

    public void SomeMethod()
    {
        _someGenericInterface.SomeMethod();
    }
}

public interface INonGenericInterface
{
    void SomeMethod();
}

public interface IGenericInterface<T>
{
    void SomeMethod();
}
另一答案

虽然我不确定,但这种方法可能有所帮助。此方法使用适配器模式。

public interface ISolrOperations<T> 
{
    SqlQuery<T> Execute();
}

public interface ISolrOperationsAdapter
{
    IEnumerable<Base> Execute();
}

//Idealy you have interfaces
public class Base { }
public class Class1 : Base { }
public class Class2 : Base { }  

public abstract class SolrOperationsAdapter : ISolrOperationsAdapter
{
    protected SolrOperationsAdapter()
    {
    }

    public IEnumerable<Base> Execute()
    {
        return ExecuteImpl();
    }

    protected abstract IEnumerable<Base> ExecuteImpl();
}


public class GenericSolrOperationsAdapter<T> : SolrOperationsAdapter
{
    private readonly ISolrOperations<T> _solrOperations;

    public static ISolrOperationsAdapter From(ISolrOperations<T> solrOperations)
    {
        return new GenericSolrOperationsAdapter<T>(solrOperations);
    }

    protected GenericSolrOperationsAdapter(ISolrOperations<T> solrOperations)
        : base()
    {
        _solrOperations = solrOperations;
    }

    //If you define interfaces you can return return IEnumerable<IInterface>
    protected override IEnumerable<Base> ExecuteImpl()
    {
        //here you can somehow convert result of query to your types(Class1, Class2 or some interface behind)
        return _solrOperations.Execute().ConvertTo<IEnumerable<Base>>();
    }
}

用法示例:

ISolrOperations<Class1> solrOperations = new SolrOperationsImplementation()
ISolrOperationsAdapter adapter = GenericSolrOperationsAdapter<Class1>.From(solrOperations);
IEnumerable<Base> result = adapter.Execute(); 

以上是关于如何将不同的泛型类分配给同一个变量的主要内容,如果未能解决你的问题,请参考以下文章

受保护的泛型类 - 是不是支持?

2018-7-26-随笔-泛型

在 Typescript 的泛型类中初始化泛型类型

JAVA中的泛型类是啥东西?

无法将X类型转换为T.泛型类中的泛型委托

(十七)泛型程序设计