简体   繁体   English

如何将对象转换为泛型类型?

[英]How to cast object to generic type?

I have many classes that implements IBuilder<> interface such the ones below 我有很多实现IBuilder <>接口的类,如下所示

UPDATED: each Model1, Model2... inherits from IModel 更新:每个Model1,Model2 ...都继承自IModel

public class A : IBuilder<Model1>
{
     public Model1 Create(string param)
     {
         return new Model1();
     }
}
public class B : IBuilder<Model2>
{
     public Model2 Create(string param)
     {
          return new Model2();
     }
}

I'm using StructureMap to register all classes that inherit IBuilder<> 我正在使用StructureMap来注册继承IBuilder <>的所有类

Scan(x =>
{
       x.TheCallingAssembly();
       x.AddAllTypesOf(typeof(IViewModelBuilder<>));                
});

UPDATED 更新

Now, every time I need to get model of some Module I call Do function 现在,每次我需要获得一些模块的模型我都会调用Do函数

public IModel Do(Module module)
{
        //ModelSettings is taken from web.config  
        var builderType = Type.GetType(string.Format("{0}.{1}ModelBuilder,{2}", ModelSettings.Namespace, module.CodeName, ModelSettings.Assembly));
        var builder = ObjectFactory.GetInstance(t) as IViewModelBuilder<>;

        return builder.Create("");            
}

I get compilation error in the line ObjectFactory.GetInstance(t) as IViewModelBuilder<> . 我在ObjectFactory.GetInstance(t) as IViewModelBuilder<>行中得到编译错误, ObjectFactory.GetInstance(t) as IViewModelBuilder<> Many posts suggest to create NOT generic interface(IViewModelBuilder) and let the generic one to inherit it. 许多帖子建议创建NOT通用接口(IViewModelBuilder)并让通用接口继承它。 And then I could make the casting like 然后我就可以像铸造一样

ObjectFactory.GetInstance(t) as IViewModelBuilder

Is this the only way? 这是唯一的方法吗?

Thank you 谢谢

Your code for Do and GetInstance should be generic too. 您的DoGetInstance代码GetInstance应该是通用的。 Basicly it could look something like this 基本上它可能看起来像这样

public T Do<T> ()
{
     return ObjectFactory.GetInstance<T>().Create();
}

Couldn't you make Do() generic? 难道你不能使Do()通用吗?

var m = Do<B>();

public T Do<T>()
{ 
   var builder = (IViewModelBuilder<T>)ObjectFactory.GetInstance(typeof(T));
   return builder.Create("");
}

If you can't, using non-generic interface is probably your best bet, but there are other options like using reflection or C# 4's dynamic : 如果你不能,使用非通用接口可能是你最好的选择,但还有其他选择,如使用反射或C#4的dynamic

var m = Do(typeof(B));

public object Do(Type t)
{ 
   dynamic builder = ObjectFactory.GetInstance(t);
   return builder.Create("");
}

The only thing I can think of is that you make an interface or a base class that your viewmodel inherit from. 我唯一能想到的是你创建了一个你的viewmodel继承的接口或基类。 Ie: 即:

public class Model1 : ModelBase
{
}

public class ModelBase
{
}

public ModelBase Do(Type t)
{
    var builder = ObjectFactory.GetInstance(t);
    return t.GetMethod("Create").Invoke(builder, new object[] { "" }) as ModelBase;
}

You need to introduce a non-generic IViewModelBuilder interface if you want to call it in a non-generic scenario. 如果要在非泛型场景中调用它,则需要引入非泛型IViewModelBuilder接口。 The generic IViewModelBuilder<T> would implement IViewModelBuilder . 通用IViewModelBuilder<T>将实现IViewModelBuilder

The only other alternative is to invoke the create method via reflection, but I don't see why that would be preferred: 唯一的另一种选择是通过反射调用create方法,但我不明白为什么这是首选的:

var builder = ObjectFactory.GetInstance(builderType);
var method = builderType.GetMethod("Create");
return (IModel) method.Invoke(builder, new[]{""});

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM