如何初始化具有另一个接口类型的类型参数的接口
本文关键字:接口类型 类型参数 接口 另一个 初始化 | 更新日期: 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
上执行通用代码,最后(此时您已经拥有该类型(将其转换回特定类型。