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[]{""});
精彩评论