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

実際には実行時コードを使用して確立しましたが、コンパイラは静的に同じ知識を持っていません。コンパイラは、メソッドの型パラメーターと正確に一致するtype のオブジェクトを返すことを期待しています。LOCAL_TYPEFavoritePlaceLOCAL_TYPE

この状況を考えてみてください: 誰かが次の電話をかけます -

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

の内部RemoteToLocalに入り、いくつかの条件を経て、結果を返す時が来ました。あなたが呼ぶ

return new FavoritePlace(remoteObject as RemotePlaceType1);

コード内のこのブランチに到達することは不可能であることがわかっています。これは、実行時チェックがそこからあなたを守っているからです。

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

ただし、コンパイラは、この return ステートメントに到達できると想定する必要があります。これは、が でLOCAL_TYPEない場合にエラーになりますFavoritePlace

ここでジェネリックの使用を再考することをお勧めします。コード スニペットから、結果を呼び出し元で目的の型に型キャストすることを避けるためにジェネリック引数が必要であるように見えます。RemoteToLocalただし、呼び出し元は、内部の変換が成功したかどうかを確認するために、追加のチェックを実行する必要があります。この場合、メソッド

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

コンパイラをだます変換がなく、呼び出しコードの構造が同じままであるため、タスクにも同様に適している可能性があります。

于 2013-01-27T12:29:48.037 に答える