1

我有一个像这样的通用函数:

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 呢?不是可转换为关系传递吗?

4

2 回答 2

2

问题是FavoritePlace不一定是LOCAL_TYPE. 如果你有

class OtherEntity : EntityBase { }

FavoritePlace那么你打电话时不能返回

var entity = RemoteToLocal<OtherEntity>(remoteObject);

如果您知道转换是安全的,则可以通过强制转换绕过它:

return (LOCAL_TYPE)(object)new FavoritePlace(remoteObject as RemotePlaceType1);
于 2013-01-27T12:29:37.763 回答
1

虽然你已经建立了通过运行时的代码其实LOCAL_TYPE静态FavoritePlace的,编译器并不具备同样的知识。编译器希望您返回一个 type 的对象,与方法的类型参数完全匹配。LOCAL_TYPE

想到这种情况:有人打了以下电话——

var res = RemoteToLocal<MostHatedPlace>(remoteObj); // MostHatedPlace derives from EntityBase

现在你在里面RemoteToLocal,你经历了一些条件,现在是时候返回结果了。你打电话

return new FavoritePlace(remoteObject as RemotePlaceType1);

你知道代码中的这个分支是不可能到达的,因为有一个运行时检查可以保护你:

if (t == typeof(FavoritePlace)) {
    ....
}

但是,编译器必须假设到达这个 return 语句是可能的,这在LOCAL_TYPEis not a的情况下是错误的FavoritePlace

您可能需要在这里重新考虑泛型的使用:从代码片段看来,您需要泛型参数来避免将结果类型转换为调用者中所需的类型。但是,调用者将需要执行额外的检查以查看您内部的转换RemoteToLocal是否成功。在这种情况下,一种方法

private EntityBase RemoteToLocal(RemoteObjectBaseType remoteObject) {
    ....
}

可能同样适合该任务,因为它不会有欺骗编译器的转换,并且调用代码的结构将保持不变。

于 2013-01-27T12:29:48.037 回答