开发者

How to cast object to generic type?

I have many classes that implements IBuilder<> interface such the ones below

UPDATED: each Model1, Model2... inherits from 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<>

Scan(x =>
{
       x.TheCallingAssembly();
       x.AddAllTypesOf(typeof(IViewModelBuilder<>));             开发者_运维百科   
});

UPDATED

Now, every time I need to get model of some Module I call Do function

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<>. Many posts suggest to create NOT generic interface(IViewModelBuilder) and let the generic one to inherit it. 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. Basicly it could look something like this

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


Couldn't you make Do() generic?

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:

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. I.e:

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. The generic IViewModelBuilder<T> would implement IViewModelBuilder.

The only other alternative is to invoke the create method via reflection, but I don't see why that would be preferred:

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜