C# 受约束泛型参数从子类型到超类型的转换
我有这样一个通用函数:C# 受约束泛型参数从子类型到超类型的转换,c#,generics,type-conversion,.net-4.5,C#,Generics,Type Conversion,.net 4.5,我有这样一个通用函数: private LOCAL_TYPE RemoteToLocal<LOCAL_TYPE>(RemoteObjectBaseType remoteObject) where LOCAL_TYPE: EntityBase { Type t = typeof(LOCAL_TYPE); if (t == typeof(FavoritePlace)) { return new
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);
}
}
现在我很高兴。但我只是想知道,如果从编译器的角度来看,这种转换是可能的,为什么直接转换为本地类型是不可能的呢?不是可以转换为关系传递吗?问题是
收藏地点
不一定是本地类型的类型。
如果你有
class OtherEntity : EntityBase { }
那么您在呼叫时无法返回FavoritePlace
var entity = RemoteToLocal<OtherEntity>(remoteObject);
虽然您通过运行时代码确定LOCAL\u TYPE
实际上是FavoritePlace
,但编译器静态上并不具备相同的知识。编译器希望您返回类型为LOCAL\u type
的对象,该对象与方法的类型参数完全匹配
想想这种情况:有人打了以下电话-
var res = RemoteToLocal<MostHatedPlace>(remoteObj); // MostHatedPlace derives from EntityBase
您知道代码中的这个分支是不可能到达的,因为有一个运行时检查可以防止您:
if (t == typeof(FavoritePlace)) {
....
}
但是,编译器必须假设可以到达此返回语句,这在LOCAL\u TYPE
不是FavoritePlace
的情况下是错误的
您可能需要在这里重新考虑泛型的使用:从代码段来看,您似乎需要泛型参数,以避免将结果类型转换为调用者中所需的类型。但是,调用方随后需要执行额外的检查,以查看RemoteToLocal
中的转换是否成功。在本例中,一个方法
private EntityBase RemoteToLocal(RemoteObjectBaseType remoteObject) {
....
}
可能同样适用于该任务,因为它不存在欺骗编译器的转换,并且调用代码的结构将保持不变。Derived1从Base继承,Derived2从Base继承。那么,你能把Derived1转换成Derived2吗?在您的示例中,Derived2是本地类型,Derived1是FavoritePlace,Base是EntityBase。强制转换操作符实际上可以执行一些完全不同的操作。它可以安全地强制转换为基类型(FavoritePlace
→ <代码>EntityBase
),它还可以强制转换为派生类型(EntityBase
→ LOCAL_TYPE
,这可能会引发异常),但它不能在一个步骤中从一个子类转换到另一个子类。更新了问题。关于泛型的使用:我需要它们将有关本地类型的信息传递给函数,函数用于决定执行哪个分支,以便构造正确的本地类型。但是,从某种意义上讲,您是对的,返回类型不必是泛型参数,也可以是EntityBase。显然,类型转换没有问题。谢谢你的好主意!我接受了另一个答案,因为它显示了如何摆脱这个问题,但你的答案也很有用,所以我给它+1.)
return new FavoritePlace(remoteObject as RemotePlaceType1);
if (t == typeof(FavoritePlace)) {
....
}
private EntityBase RemoteToLocal(RemoteObjectBaseType remoteObject) {
....
}