F#:使用C#中的F#索引属性

时间:2015-04-01 14:00:29

标签: f#

我在F#中编写了一个实现接口的类,以便为我的F#-assembly构建一个C#友好的接口。

我已将一些属性写为索引属性。但是,当我尝试使用C#中的类型时,我只在intellisense中获取合成的get_PropertyName方法,并且编译器同样会抱怨我想要使用索引属性,就像我对C#那样做。

参考代码:

type IMyInterfaceType =   
    abstract MyProperty : MyType1 with get
    abstract MyIndexedProperty : MyType2 -> MyType3 with get
    abstract MyTwoDimensionalIndexedProperty : (MyType4 * MyType5) -> MyType6 with get

type MyInterfaceType =   

    new () = { }

    interface IMyInterfaceType with
        member this.MyProperty with get () = new MyType1 ()
        member this.MyIndexedProperty with get parameter = new MyType3 ()
        member this.MyTwoDimensionalIndexedProperty with get pair = new MyType6 ()

当尝试从C#访问此类时,我只获取方法

get_MyIndexedProperty(MyType2 parameter)
get_MyTwoDimensionalIndexedProperty(Tuple<MyType4, MyType5>)

而不是我希望的索引属性。

我做错了什么或这是一个已知问题?

欢呼声
--Mathias。

1 个答案:

答案 0 :(得分:4)

对原始问题的回复

C#中的索引器属性具有特殊名称Item,因此要创建可从C#访问的索引器,您必须为索引器属性命名&#34;项目&#34;,例如:

type X () =
    member this.Item with get key = ....

现在可以使用(x : X).[key]在F#中访问,也可以使用x [key]在C#中访问。

对更新后问题的回应

C#不像F#那样支持索引属性。建议使用其他类型:https://msdn.microsoft.com/en-us/library/aa288464%28v=vs.71%29.aspx

所以你可以尝试使用这样的东西:

[<AbstractClass>]
type Indexer<'index, 'result> () =
    abstract Get : 'index -> 'result
    member this.Item with get key = this.Get key

type IMyInterfaceType =   
    abstract MyProperty : MyType1 with get
    // F# indexed propetties
    abstract MyIndexedProperty : MyType2 -> MyType3 with get
    // C# workaround
    abstract MyCSharpIndexedProperty : Indexer<MyType2, MyType3> with get

type MyInterfaceType () as this =
    let proxy =
      { new Indexer<MyType2, MyType3> () with
          member __.Get key = (this :> IMyInterfaceType).MyIndexedProperty key }
    interface IMyInterfaceType with
        member __.MyProperty with get () = new MyType1 ()
        member __.MyIndexedProperty with get key = new MyType3 ()
        member __.MyCSharpIndexedProperty with get () = proxy

和二维属性类似,通过创建Indexer<'index1, 'index2, 'result> () = ...