2013-08-16 23 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);