5

C#で次のCRTPタイプを指定します。

public abstract class DataProviderBase<TProvider>
    where TProvider : DataProviderBase<TProvider> { }

F#でジェネリック型の定義を取得するにはどうすればよいですか?

let typeDef = typedefof<DataProviderBase<_>>

エラーが発生します:

型推論変数にデフォルトの型'DataProviderBase<'a>'を適用すると、型制約が一致しません。''a'と'DataProviderBase<'a>'を統合すると、結果の型は無限になります。さらに型制約を追加することを検討してください。

C#では、次のようになります。

var typeDef = typeof(DataProviderBase<>);

アップデート

回避策を見つけました:

[<AbstractClass>]
type DummyProvider() =
  inherit DataProviderBase<DummyProvider>()

let typeDef = typeof<DummyProvider>.BaseType.GetGenericTypeDefinition()

余分なタイプなしでそれを行う別の方法はありますか?

4

1 に答える 1

5

これは実際には非常に良い質問だと思います。これに対するより良い回避策は見つかりませんでした。typedefof次のように使用することで、回避策をわずかに簡素化できます。

let typeDef = typedefof<DataProviderBase<DummyProvider>>

技術詳細

問題は、F#typedefof<'T>は型引数を取る通常の関数にすぎないことです (typeof演算子である C# とは異なります)。それを呼び出すには、実際の型を指定する必要があり、関数は隠れて呼び出しますGetGenericTypeDefinition

機能する理由typedefof<option<_>>は、F# が既定の型を引数として指定するためです (この場合はobj)。一般に、F# は、制約に一致するあまり具体的でない型を選択します。あなたの場合:

DataProviderBase<_> などになり DataProviderBase<DataProviderBase<_>>ます。

(回避策のように)新しい型を定義しない限り、の型引数として使用できる具体的な型typedefof<...>はありません。この場合、デフォルトのメカニズムは単純に機能しません...

于 2011-07-21T22:20:57.873 に答える