2011-06-20 70 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[]{""});