7

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

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 及其类型暗示了“IModel”,为什么它不能初始化映射器。

有没有另一种方法来构建它以实现我所需要的?

太感谢了

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

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

显然,当它在“out”处声明时,您不能将泛型类型作为输入参数

4

2 回答 2

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

没有“out T”,你能做的最好的就是:

IGenericMapper<ActualModel> blah = new ActualMapper();

这是一个兔子洞,所以要小心,特别是如果你想把两者混在一起:)

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

[编辑]

如果您希望能够向下转换 generic T,那么它必须是out并且您不能将其用作输入。但是,您可以在您的实施中将其中一些实时移动;即检查是否可以将其转换为模型类型。

interface IGenericMapper<out TModel, in TKeyOrIdent> 

TModel GetModel(TKeyOrIdent bBusinessObject);
void SetModel(object model, TKeyOrIdent target);
于 2013-08-16T13:26:01.010 回答
4

你必须定义

IGenericMapper<out T>

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

简单IGenericMapper<IModel>!=IGenericMapper<ActualModel>即使ActualModel : IModel

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

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

不要在假设您可以在任何地方消除强制转换的情况下使用泛型。我已经尝试过了,C# 根本没有所需的功能。

我建议使用一个IGenericMapper接口作为基本接口,IGenericMapper<T>然后在上面执行通用代码IGenericMapper,最后(此时您已经拥有类型)将其转换回特定类型。

于 2013-08-16T13:25:09.127 回答