Given the following CRTP type in C#:
public abstract class DataProviderBase<TProvider>
where TProvider : DataProviderBase<TProvider> { }
How would I get its generic type definition in F#?
let typeDef = typedefof<DataProviderBase<_>>
yields the error:
Type constraint mismatch when applying the default type 'DataProviderBase<'a>' for a type inference variable. The resulting type would be infinite when unifying ''a' and 'DataProviderBase<'a>' Consider adding further type constraints
In C#, it would be:
var typeDef = typeof(DataProviderBase<>);
I found a workaround:
[<AbstractClass>]
type DummyProvider() =
inherit DataProviderBase<DummyProvider>()
let typeDef = typeof<DummyProvider>.BaseType.GetGenericTypeDefinition()
Is there another way to do it, without the extra type?
A generic type definition is a template from which other types can be constructed. For example, from the generic type definition G<T> (expressed in C# syntax; G(Of T) in Visual Basic or generic <typename T> ref class G in C++) you can construct and instantiate the type G<int> ( G(Of Integer) in Visual Basic).
I think this is actually a very good question. I didn't find a better workaround for this.
You can slightly simplify your workaround by using typedefof
like this:
let typeDef = typedefof<DataProviderBase<DummyProvider>>
TECHNICAL DETAILS
The problem is that F#'s typedefof<'T>
is just an ordinary function that takes a type argument (unlike typeof
in C#, which is an operator). In order to call it, you need to give it an actual type and the function will then call GetGenericTypeDefinition
under the cover.
The reason why typedefof<option<_>>
works is that F# specifies a default type as an argument (in this case obj
). In general, F# chooses the less concrete type that matches the constraints. In your case:
DataProviderBase<_>
will become DataProviderBase<DataProviderBase<_>>
and so on.
Unless you define a new type (as in your workaround), there is no concrete type that could be used as a type argument of typedefof<...>
. In this case, the defaulting mechanism simply doesn't work...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With