Reputation: 112
I'm trying to create an attribute in F# with positional arguments but failing all the time.
type ColumnAttribute(?index:int,?name:string) =
inherit Attribute()
let mutable index = index
let mutable name = name
member x.Index
with get() = index
and set value = index <- value
member x.Name
with get() = name
and set value = name <- value
type Substance = {
[<Column(Index=1)>] Name : string
[<Column(Index=0)>] Id : int
[<Column(Name="sequence")>] Sequence : string
}
I've tried several different approaches but this is the closest I ended with.
Upvotes: 2
Views: 691
Reputation: 1685
I was able to get this working using the alternative syntax documented for optional arguments
type NamedAttribute([<Optional>] [<DefaultParameterValue("")>] name) =
inherit Attribute()
new () = new NamedAttribute(?name = None)
member val Name:string = name
module X =
[<Command(name = "")>]
let f x = x
Upvotes: 0
Reputation: 47904
This works:
type ColumnAttribute() =
inherit System.Attribute()
let mutable index = 0
let mutable name = ""
member x.Index
with get() = index
and set value = index <- value
member x.Name
with get() = name
and set value = name <- value
type Substance = {
[<Column(Index=1)>] Name : string
[<Column(Index=0)>] Id : int
[<Column(Name="sequence")>] Sequence : string
}
Attributes already support property setter syntax similar to named arguments. To get what you want, use a parameterless constructor and rely on the attribute syntax, instead of named arguments (which don't work well with attributes anyway, because they're inferred as option
s...which don't qualify as constant expressions).
Upvotes: 2
Reputation: 754585
There are 2 issues that I see with your code
ColumnAttribute
.Index
and Name
is int option
and string option
respectively but you need it to be int
and string
.Try the following
type ColumnAttribute(index:int option,name:string option) =
inherit Attribute()
let mutable index = index
let mutable name = name
new () = ColumnAttribute (None, None)
member x.Index
with get() = match index with | Some i -> i | None -> 0
and set value = index <- Some value
member x.Name
with get() = match name with | Some n -> n | None -> ""
and set value = name <- Some value
type Substance = {
[<Column(Index=1)>] Name : string
[<Column(Index=0)>] Id : int
[<Column(Name="sequence")>] Sequence : string }
Upvotes: 4
Reputation: 118865
Here you go:
open System
type ColumnAttribute() =
inherit Attribute()
let mutable index = 0
let mutable name = ""
member x.Index
with get() = index
and set value = index <- value
member x.Name
with get() = name
and set value = name <- value
type Substance = {
[<Column(Index=1)>] Name : string
[<Column(Index=0)>] Id : int
[<Column(Name="sequence")>] Sequence : string
}
Note that the optional parameters (e.g. ?index
) in your original attempt were causing the types to be e.g. int option
rather than int
.
Upvotes: 0