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

本文关键字:接口类型 类型参数 接口 另一个 初始化 | 更新日期: 2023-09-27 18:27:53

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

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

它不编译。我收到错误

无法将类型"实际映射器"隐式转换为"IGenericMapper"。 存在显式转换(您是否缺少强制转换?

当我使用

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

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

我错过了什么 - 由于ActualMapper()实现了IGeneric映射器并且其类型暗示了"IModel",为什么它不能初始化映射器。

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

非常感谢

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

T GetModel(busO bBusinessObject);
busO  SetBusObject(T source, busO  target);
显然,当泛型类型

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

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

很确定您正在通过通用更改进入协变领域;

试试这个:

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

你必须定义

IGenericMapper<out T>

以支持你的方案,但这会应用其他限制。

只需IGenericMapper<IModel> != 即使ActualModel : IModel IGenericMapper<ActualModel>

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

然后,可以选择在实现上显式实现接口成员。请参阅List<T>.GetEnumerator() : IEnumerable

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

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