F#:使用来自 C# 的索引为 属性 的 F#
F#: Using a F# indexed property from C#
我在 F# 中编写了一个 class 实现接口,以便为我的 F# 程序集构建一个 C# 友好的接口。
我已经将一些属性写为索引属性。但是,当我尝试使用 C# 中的类型时,我只能在智能感知中获得合成 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# 访问这个 class 时,我只得到方法
get_MyIndexedProperty(MyType2 parameter)
get_MyTwoDimensionalIndexedProperty(Tuple<MyType4, MyType5>)
而不是我希望的索引属性。
我是不是做错了什么或者这是一个已知问题?
干杯
--Mathias.
原题回复:
C# 中的索引器属性具有特殊名称 Item
因此要创建可从 C# 访问的索引器,您必须将索引器命名为 属性 "Item",例如:
type X () =
member this.Item with get key = ....
现在可以在 F# 中使用 (x : X).[key]
或在 C# 中使用 x[key] 访问它。
对更新问题的回应:
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> () = ...
我在 F# 中编写了一个 class 实现接口,以便为我的 F# 程序集构建一个 C# 友好的接口。
我已经将一些属性写为索引属性。但是,当我尝试使用 C# 中的类型时,我只能在智能感知中获得合成 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# 访问这个 class 时,我只得到方法
get_MyIndexedProperty(MyType2 parameter)
get_MyTwoDimensionalIndexedProperty(Tuple<MyType4, MyType5>)
而不是我希望的索引属性。
我是不是做错了什么或者这是一个已知问题?
干杯
--Mathias.
原题回复:
C# 中的索引器属性具有特殊名称 Item
因此要创建可从 C# 访问的索引器,您必须将索引器命名为 属性 "Item",例如:
type X () =
member this.Item with get key = ....
现在可以在 F# 中使用 (x : X).[key]
或在 C# 中使用 x[key] 访问它。
对更新问题的回应:
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> () = ...