如何初始化具有另一个接口类型的类型参数的接口

时间:2013-08-16 13:19:17

标签: c#

我遇到了一个问题 - 这是我的班级结构

public interface IModel{}

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

public class ActualModel:IModel {...}

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

我初始化映射器的实际代码是:

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

它无法编译。我收到了错误

  

无法将类型'ActualMapper'隐式转换为'IGenericMapper'。   存在显式转换(您是否错过了演员?)

当我使用

进行投射时
mapper= new ActualMapper() as IGenericMapper<IModel>;

映射器未正确初始化(它返回为NULL)

我错过了什么 - 因为ActualMapper()实现了IGeneric Mapper及其类型impliments`IModel'为什么它不能初始化mapper。

有没有其他方法来构建这个以实现我需要的东西?

非常感谢

注意人们提出的解决方案给了我其他编译错误,因为映射接口具有以下成员

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

显然,当它在“out”

声明时,你不能将泛型类型作为输入参数

2 个答案:

答案 0 :(得分:5)

非常确定你正在通过Generic改变进入协变领域;

试试这个:

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

没有'out 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);

答案 1 :(得分:4)

你必须定义

IGenericMapper<out T>

支持您的方案,但这适用于其他限制。

即使IGenericMapper<IModel>

,也只需IGenericMapper<ActualModel>!= ActualModel : IModel

在大多数情况下,拥有一个非通用的基本接口是有意义的。例如,请参阅IList<T>,它实现了IList

然后,您可以选择实现来显式实现接口成员。见List<T>.GetEnumerator() : IEnumerable

假设您可以消除任何地方的投射,请不要使用泛型。我试过它C#根本就没有这个所需的功能。

我建议将IGenericMapper接口作为IGenericMapper<T>的基本接口,然后在IGenericMapper上执行通用代码,最后(并且此时已经有类型)将其强制转换为特定类型。