2011-06-20 65 views
4

我有一个实现IBuilder <>接口,下面如何将对象转换为泛型?

那些已更新许多类: 每个模型1,模型2 ...从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(); 
    } 
} 
我使用StructureMap到

注册所有继承的类IBuilder <>

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

修订

现在,每当我需要一些模块我称之为的模型时做功能

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

我得到的编译错误在该行ObjectFactory.GetInstance(t) as IViewModelBuilder<>。 许多帖子建议创建不是通用接口(IViewModelBuilder)并让通用接口继承它。然后我就可以制作像

ObjectFactory.GetInstance(t) as IViewModelBuilder 

这是唯一的方法吗?

谢谢

+0

你的实际代码非常混乱混合的示例代码。 IViewModelBuilder如何与IBuilder相关联,A类实际上是否以其名称中的模型构建器结束?等 –

回答

2

难道你不能让Do()通用?

var m = Do<B>(); 

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

如果不能,使用非通用接口可能是你最好的选择,但也有像使用反射或C#4的dynamic其它选项:

var m = Do(typeof(B)); 

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

我不能做**做**通用,因为我创建的类型,Do将在运行时接收。是动态实用还是重写我的代码更好?我只是不明白如何在运行时获取类型如何重写 – theateist

+0

在我看来,代码中根本不需要泛型。只需使用非泛型'IViewModelBuilder',返回'IModel'。 – svick

5

你的代码DoGetInstance应该是通用的了。基本上它可能看起来像这样

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

我不能使**做**通用,因为我创建了类型,Do会在运行时收到 – theateist

+0

我已经更新了我的帖子,并添加了我使用的真实代码。我会很高兴,如果你可以看看 – theateist

1

我唯一能想到的是你制作了一个你的视图模型继承的接口或基类。即:

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; 
} 
+0

@Torbjon,我已经在使用某种ModelBase。如果有帮助,我更新了我的帖子。我想避免使用'Invoke',因为如果我将'Create'更改为'Create2',我会忘记在'GetMethod'中更改它,但使用真实接口如果我要更改方法的名称,则会出现编译错误 – theateist

1

你需要的,如果你想调用它在非一般情况下引入非通用IViewModelBuilder接口。通用IViewModelBuilder<T>将执行IViewModelBuilder

唯一的其他选择是通过反射调用create方法,但我不明白为什么会被优先考虑:

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