Reputation: 9934
I am struggling with a seeming trivial problem concerning generics.
I have these methods
let toTypedCollection r l =
l |> List.iter (fun x -> r.Add(x)
r
let toRowDefinitions = toTypedCollection (new RowDefinitionCollection())
let toColsDefinitions = toTypedCollection (new ColumnDefinitionCollection())
where
public sealed class ColumnDefinitionCollection : DefinitionCollection<ColumnDefinition>
and
public sealed class RowDefinitionCollection : DefinitionCollection<RowDefinition>
Now I get an compiler error telling me that r.Add
needs to be augmented with type information. So I do this
let toTypedCollection (r:DefinitionCollection<_>) l = ...
The problem now however is that the resulting signature for toRowDefinitions
looks like
DefinitionCollection<RowDefiniton> -> list RowDefinition -> DefinitionCollection<RowDefinition>
That is all fine - except for the return type. I absolutely need to have a RowDefinitonCollection
instead of DefinitionCollection<RowDefinition>
Has anybody an idea on how to accomplish this?
Upvotes: 0
Views: 92
Reputation: 13577
Try let toTypedCollection<'T> (r: #DefinitionCollection<'T>) l = ...
.
The #
solves the problem for me on a simple sample, though you might need to annotate toRowDefinitions
/toColsDefinitions
to pin down the exact return types as well.
Upvotes: 2
Reputation: 6223
I think you are looking for something like this:
let toTypedCollection (r : 'T when 'T :> ICollection<_>) l =
l |> List.iter (fun x -> r.Add(x))
r
where ICollection<_>
is the one from System.Collections.Generic
, but of course, you could use DefinitionCollection<_>
if you need the concrete type.
scrwtp's answer shows a shorter notation to achieve a similar type annotation without naming 'T
: Instead of 'T when 'T :> ICollection<_>
, you can also write #ICollection<_>
. In this case, 'T
isn't used elsewhere, so this notation is shorter.
There is also the less type-safe way of making toTypedCollection
inline and adding a static member constraint that r
needs an Add
method; but with that, it would work on any type with an Add
method, which usually isn't a good idea.
Upvotes: 1