Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Interface F#接口和属性_Interface_F#_Automatic Properties - Fatal编程技术网

Interface F#接口和属性

Interface F#接口和属性,interface,f#,automatic-properties,Interface,F#,Automatic Properties,我试图掌握F#,在这个过程中我转换了一些C代码。我在接口中定义属性并在类型中实现它们时遇到了一些问题 考虑以下代码: module File1 type IMyInterface = abstract member MyProp : bool with get, set abstract member MyMethod : unit -> unit type MyType() = interface IMyInterface with memb

我试图掌握F#,在这个过程中我转换了一些C代码。我在接口中定义属性并在类型中实现它们时遇到了一些问题

考虑以下代码:

module File1

type IMyInterface =
    abstract member MyProp : bool with get, set
    abstract member MyMethod : unit -> unit

type MyType() = 
    interface IMyInterface with
        member val MyProp = true with get, set
        member self.MyMethod() = if MyProp then () else ()

似乎表明我在MyType中实现的MyProp是正确的,但是,编译器抱怨“没有定义值或构造函数‘MyProp’”。有什么想法吗?

这是一个有效的版本:

type IMyInterface =
    abstract member MyProp : bool with get, set
    abstract member MyMethod : unit -> unit

type MyType() = 
    member val MyProp = true with get, set
    member self.MyMethod() = if self.MyProp then () else ()
    interface IMyInterface with
        member self.MyProp with get () = self.MyProp and set v = self.MyProp <- v
        member self.MyMethod() = self.MyMethod()
类型IMyInterface=
抽象成员MyProp:bool和get,set
抽象成员MyMethod:unit->unit
类型MyType()=
成员val MyProp=true,带get,set
成员self.MyMethod()=如果self.MyProp那么()else()
接口imy接口

使用get()=self.MyProp和set v=self.MyProp的成员self.MyProp要访问(显式)接口中的属性,您需要强制转换到接口类型的
self
引用:

type MyType() = 
    interface IMyInterface with
        member val MyProp = true with get, set
        member self.MyMethod() = if (self :> IMyInterface).MyProp then () else ()
如果显式实现接口,并且访问成员还需要强制转换,则在C#中会出现相同的错误:

interface IMyInterface
{
    bool MyProp { get; set; }
    void MyMethod();
}

class MyType : IMyInterface
{
    bool IMyInterface.MyProp { get; set; }

    void IMyInterface.MyMethod()
    {
        if (((IMyInterface)this).MyProp) { }
    }
}

如果只访问接口,则不需要在类型本身中定义成员。 如果你想要极简主义,菲尔的答案是好的,但是另一种方法 我喜欢使用“let bound”值而不是成员——对于更复杂的代码,类型推断更好 他们通常比会员更容易相处

type MyType() = 
    let mutable myProp = true 
    let myMethod() = if myProp then () else ()

    interface IMyInterface with
        member __.MyProp with get() = myProp and set v = myProp <- v
        member __.MyMethod() = myMethod()
type MyType()=
设可变myProp=true
让myMethod()=如果是myProp,那么()else()
接口imy接口

使用get()=MyProp和set v=MyProp try
self.MyProp
-您需要
这个
限定符;)@Carsten似乎不适用于自动属性我知道这是可行的,但我想要的是自动属性,而不是显式的支持字段…
MyProp
是一个自动属性-只是接口实现覆盖了它-也许有一个较短的方法,但老实说,我还是尽量不使用可变值,所以我不确定;)@依我的经验,F#在功能上使用时非常优雅,但在面向对象的方式中使用时会变得“混乱”。这促使您转而选择漂亮的功能设计:)这只是因为您没有隐式接口,所以您要么必须做两次特定的事情(如这里所示),要么必须做
(myType:>IMyInterface).MyProp
一直以来-正如Mark评论的那样,如果你试图以1:1的比例复制你从C#@Eyvind那里知道的东西,你会不高兴的。我认为类型推断和隐式转换之间是有区别的。F#将为您推断类型,就好像您已经显式地对它们进行了注释一样,但它不会隐式地将类向上转换为接口或基类(除了某些例外)。它也不会隐式地将int转换为float,甚至不会将int64转换为int32!我想这就是卡斯滕所说的。你可以在C语言中做很多事情,F会抱怨这些事情,迫使你明确自己的意图。过了一段时间,你甚至会喜欢上所有的抱怨!啊哈!我不知道这实际上是一个显式接口实现。有没有隐式实现的方法?据我在F#中所知,所有接口都必须显式实现。Scott在这里很好地解释了这一点,没有问题,是的,在F#中,接口只能被明确地实现。我喜欢这样想:(a)我使用let绑定值和函数(比如,相当于私有方法)完成所有实际工作,然后(b)我通过一个或多个接口公开一些功能。然后,接口只是“真实”代码的代理。