2011-03-16 30 views
1

我试图用位置参数在F#中创建一个属性,但一直失败。属性中的F#位置参数

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 
} 

我试过几种不同的方法,但这是最接近我结束了。

回答

3

有2个问题,我用你的代码

  1. 看到为了这个工作,你需要定义一个无参数的构造函数ColumnAttribute
  2. 类型的IndexNameint optionstring option分别,但你需要它intstring

请尝试以下

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 } 
+0

这也不起作用。这个szenario真的在fsharp中工作吗?嗯。这真的很奇怪。我真正想要的是具有选项的属性。所以我想我必须创建一个可为空(或使用伪空值,例如对于索引-1和用于命名EmptyString)。我的意图是使用这两个属性作为选项索引或名称来识别csv文件中的列 – 2011-03-16 20:42:47

+0

@Rainer,我不确定您的意思是“这不起作用”。我已经在Visual Studio 2010 RTM – JaredPar 2011-03-16 22:04:09

+0

中成功编译过了。在一个干净的脚本中再次尝试。现在它工作!我认为它是我如何使用属性的问题。我真的好奇为什么这不起作用。我知道你对fsharp有很好的了解。猜猜这是与我如何使用该属性有关的错误。将再次检查我的代码库! – 2011-03-17 09:35:43

2

这工作:

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 
} 

属性已经支持类似命名的参数属性setter语法。为了得到你想要的,使用一个无参数的构造函数并且依赖于属性语法,而不是命名参数(这对于属性来说并不是很好,因为它们被推断为option ......这不符合常量表达式)。

+0

我USEE让可变指数= -1,因为列可以是基于0的,而且我也必须有索引和列之间的选项。那么对于一个属性是否可以进行空的处理呢,或者这是对它的方式。 MSDN对此声明不太清楚,因为他们建议使用位置参数和属性getter/setter方法。无论如何。这工作。我非常热衷于使用我忘记了简单方法的选项。 – 2011-03-16 20:58:35

+0

@Rainer - 你遇到了CLR限制。在元数据中表示时,属性的构造函数参数(和字段/属性设置器)只能包含类型System.Type,string,char,bool,float,float32,类型,枚举或这些类型的数组。由于没有办法在属性元数据中存储'string option'或'int option'类型的值,所以必须使用类似Daniel的方法。 – kvb 2011-03-16 22:13:31

0

在这里你去:

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 
} 

注意,可选参数(例如?index)在原来的尝试都导致类型是如int option而不是int