简体   繁体   English

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

[英]How to assign different generic classes to same variable

I know this question has probably been asked many times and my title probably needs some help so feel free to close this question after pointing me to a duplicate... just not sure how to properly search for the answer at the moment. 我知道这个问题可能已经被问过很多次了,我的书名可能需要一些帮助,因此在将我指向重复的对象后可以随时结束这个问题……只是不确定目前如何正确地寻找答案。

I've got a situation where a variable may need to hold and instance of ISolrOperations<Class1> or it may need to hold an instance of ISolrOperations<Class2> . 我遇到一种情况,其中变量可能需要保存ISolrOperations<Class1>实例,或者它可能需要保存ISolrOperations<Class2>的实例。 The problem is that there is no base version of the interface and so there's no class I can define the variable as (other than object, which obviously has no knowledge of ISolrOperations<T> 's methods) to be able to hold either class. 问题在于该接口没有基础版本,因此没有类可以定义为变量(对象除外,该对象显然不了解ISolrOperations<T>的方法)可以容纳这两个类。

So the only solutions I know of are either a) Do an if/else statement where I do everything I need with ISolrOperations<Class1> in one block and everything I need in ISolrOperations<Class2> in the other block even though each block will basically contain duplicate code. 因此,我知道的唯一解决方案是:a)执行if / else语句,在其中我用ISolrOperations<Class1>在一个块中完成我需要做的一切,而在ISolrOperations<Class2>中在另一块中执行我需要做的一切,即使每个块基本上包含重复的代码。 Or b) I could make the variable dynamic and just lose some compile time validation of my code. 或者b)我可以使变量动态化,而只是失去一些对我的代码的编译时验证。

I'm trying to think if there is some way I can create a generic wrapper class that has a non-generic base. 我试图考虑是否可以通过某种方式创建具有非泛型基础的泛型包装器类。 And maybe the base has to treat it as an object but uses reflection... but them I'm like screw it; 也许底座必须将其视为对象,但要使用反射...但是它们就像螺丝钉一样。 if I have to go through that trouble may as well just use the dynamic keyword. 如果我必须解决该麻烦,也可以使用dynamic关键字。

Is there a more "proper" design pattern to handle this scenario? 有没有更“合适”的设计模式来处理这种情况? Or is my choice basically between dynamic or writing a lot of code just to make myself feel like I'm doing it "right" when dynamic is really the most practical solution? 还是在动态还是写很多代码之间做出选择,以使自己觉得在动态是最实际的解决方案时我做对了?

Edit: Actually I'm not sure if dynamic would solve this problem :/ 编辑:其实我不确定动态是否可以解决此问题:/

Edit 2: Nope... other code uses lambdas with the variable which requires casting it which I obviously don't know what to cast to at compile time so that won't work. 编辑2:不...其他代码使用带变量的lambdas要求强制转换它,我显然不知道在编译时强制转换为什么,这样就行不通了。

Although I am not sure, this approach might help. 尽管我不确定,但是这种方法可能会有所帮助。 This approach uses adapter pattern . 此方法使用适配器模式

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>>();
    }
}

Usage example: 用法示例:

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

Wrap the class in a generic adapter class that implements the required interface. 将类包装在实现所需接口的通用适配器类中。

This is called the adapter pattern in case you want to search for examples of it. 如果您要搜索它的示例,这称为适配器模式。

Example of a generic adapter: 通用适配器的示例:

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();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何以编程方式将两个不同的类分配给一个变量? - How to programmatically assign two different classes to one variable? 如何在列表中存储具有不同泛型的相同类型的类? - How do I store the same types of classes that have a different generic inside of a list? @ HTML.Partial将通用类用于不同类中的同一属性 - @HTML.Partial use generic class for the same property in different classes 在此示例中,如何将具有泛型类型的从同一接口继承的不同对象存储在单个变量中? - How can I store different objects inheriting from same interface, with generic types, in a single variable in this example? 如何对具有相同类型和名称的变量的不同结构使用通用类型参数? - How can I use a generic type parameter for different structs that have a variable with the same type and name? 如何将同一事件分配给不同的对象? - how to assign same event to different objects? 如何从不同的表分配变量? - How to assign variable from different tables? 如何将函数泛型参数分配给强类型变量? - how to assign a function generic parameter to a strongly typed variable? C#-如何在属性或变量中分配泛型类型 - C# - How to assign the generic type in a property or variable 如何在 C# 中的 ref 泛型变量上分配类型特定值? - How to assign type specific value on ref generic variable in C#?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM