2013-08-16 50 views
7

香港專業教育學院碰到一個問題的類型aguments接口 - 這是我的階級結構如何初始化的類型是另一個接口

public interface IModel{} 

public interface IGenericMapper<T> where T : IModel {...} 

public class ActualModel:IModel {...} 

public class ActualMapper: IGenericMapper<ActualModel> {...} 

我實際的代碼來initialse映射器是:

IGenericMapper<IModel> mapper; 
mapper= new ActualMapper(); 

它不編譯。我得到的錯誤

無法隱式轉換類型「ActualMapper」到「IGenericMapper」。 的顯式轉換存在(是否缺少強制轉換?)

當我使用

mapper= new ActualMapper() as IGenericMapper<IModel>; 

映射器沒有得到正確初始化投(它回來爲NULL)

我錯過了什麼 - 因爲ActualMapper() implements IGeneric映射器和它的類型impliments`IModel'爲什麼不能初始化映射器。

有沒有另外一種方法來構造這個以達到我所需要的?

謝謝你這麼多

注人提出的解決方案給了我其他的編譯錯誤映射接口具有以下成員

T GetModel(busO bBusinessObject); 
busO SetBusObject(T source, busO target); 

顯然你不能有泛型類型作爲輸入參數時其在 「走出去」

+4

你可以添加ILFFMapper <>的定義嗎? – LunicLynx

+0

'var ILFFMapper '這是一個語法錯誤,刪除'var'關鍵字 – Tommi

+0

您需要一個協變類型。嘗試IGenericMapper < out T> –

回答

4

宣佈你必須定義

IGenericMapper<out T> 

以支持您的方案,但這適用其他限制。

簡單IGenericMapper<IModel>!= IGenericMapper<ActualModel>即使ActualModel : IModel

在大多數情況下是有意義的有一個基本接口不通用。例如,參見IList<T>,它實施IList

然後,您可以選擇實現來顯式實現接口成員。請參閱List<T>.GetEnumerator() : IEnumerable

在假定您可以消除鑄造無處不在的情況下不要使用泛型。我試過了C#根本沒有這個所需的功能。

我會建議一個IGenericMapper接口作爲基本接口IGenericMapper<T>然後做你的通用代碼的IGenericMapper,最後(在這一點你已經有了類),將它轉換回特定類型。

5

很確定你正在進入共變領域,這裏是通用變化;

試試這個:

public interface IModel{} 
public interface IGenericMapper< out T> where T : IModel{} 
public class ActualModel : IModel{} 
public class ActualMapper : IGenericMapper<ActualModel> {} 

然後:

IGenericMapper<IModel> blah = new ActualMapper(); 

用了 '出T' 你能做的最好的是:

IGenericMapper<ActualModel> blah = new ActualMapper(); 

這是一個兔子洞,所以要特別小心,尤其是如果你嘗試混合兩種:)

http://msdn.microsoft.com/en-us/library/ee207183.aspx

[編輯]

如果你希望能夠向下轉型通用T,那麼它必須是out,你不能用它作爲輸入。但是,您可以在實施中將其中的一部分移至實時;即查看是否可以將其轉換爲模型類型。

interface IGenericMapper<out TModel, in TKeyOrIdent> 

TModel GetModel(TKeyOrIdent bBusinessObject); 
void SetModel(object model, TKeyOrIdent target);