我有这样的通用函数:
private LOCAL_TYPE RemoteToLocal<LOCAL_TYPE>(RemoteObjectBaseType remoteObject)
where LOCAL_TYPE: EntityBase
{
Type t = typeof(LOCAL_TYPE);
if (t == typeof(FavoritePlace))
{
return new FavoritePlace(remoteObject as RemotePlaceType1);
}
}
其中EntityBase
是非抽象类。 FavoritePlace
类继承自EntityBase
。
然而,我收到一个错误:
无法将Common.Model.FavoritePlace类型隐式转换为'LOCAL_TYPE'。
这让我想知道:FavoritePlace是EntityBase的子节点,LOCAL_TYPE被约束为EntityBase类型。为什么不能进行转换?我可能在这里遗漏了一些重要的东西。
编辑:好的,根据目前的答案和一些实验,我找到了另一种解决方法,即进行以下转换:
if (t == typeof(FavoritePlace))
{
return (LOCAL_TYPE)(EntityBase)new FavoritePlace(remoteObject);
}
现在编译器很高兴。但我只是想知道,如果从编译器的角度可以进行这样的转换,为什么不直接转换为LOCAL_TYPE? 是否可以转换为关系传递?
答案 0 :(得分:2)
问题是FavoritePlace
不一定是LOCAL_TYPE
的类型。
如果你有
class OtherEntity : EntityBase { }
然后在调用
时无法返回FavoritePlace
var entity = RemoteToLocal<OtherEntity>(remoteObject);
如果你知道转换是安全的,你可以通过演员来解决它:
return (LOCAL_TYPE)(object)new FavoritePlace(remoteObject as RemotePlaceType1);
答案 1 :(得分:1)
虽然您已通过运行时代码确定LOCAL_TYPE
实际上是FavoritePlace
,但编译器没有相同的知识静态 。编译器希望您返回类型为LOCAL_TYPE
的对象,该对象与该方法的类型参数完全匹配。
想到这种情况:有人拨打以下电话 -
var res = RemoteToLocal<MostHatedPlace>(remoteObj); // MostHatedPlace derives from EntityBase
现在你在RemoteToLocal
内,你经历了一些条件,现在是时候返回结果了。你打电话
return new FavoritePlace(remoteObject as RemotePlaceType1);
你知道代码中的这个分支是不可能达到的,因为有一个运行时检查可以保护你:
if (t == typeof(FavoritePlace)) {
....
}
但是,编译器必须假定可以达到此返回语句,如果LOCAL_TYPE
不 a FavoritePlace
,则会出错。
您可能需要在此处重新考虑泛型的使用:从代码片段看,您需要使用泛型参数来避免将结果类型转换为调用者中的所需类型。但是,调用者需要执行额外检查以查看RemoteToLocal
内的转换是否成功。在这种情况下,方法
private EntityBase RemoteToLocal(RemoteObjectBaseType remoteObject) {
....
}
可能同样适合于任务,因为它不会有欺骗编译器的转换,并且调用代码的结构将保持不变。