2016-09-04 4 views
2

今日はF#で練習することに決めました。興味深いものが1つ見つかりました。私は、C#およびF#で、しかしDAO(データアクセスオブジェクト)を使用して、かなり異なる挙動との両方のようなコードを提供しなければならない:F#クラスはプライベートメンバーとしてインターフェイスを実装しています、なぜですか?

C#バージョン:

interface IPoint2D 
{ 
    int X { get; set; } 
    int Y { get; set; } 
} 

class Point2D : IPoint2D 
{ 
    private int _x = 0; 
    private int _y = 0; 

    public int X { get { return _x; } set { _x = value; } } 
    public int Y { get { return _y; } set { _y = value; } } 
} 

F#バージョン:

type IPoint2D = 
    abstract member X: int 
    abstract member Y: int 

type Point2D(x: int, y: int) = 
    let _x = 0 
    let _y = 0 

    interface IPoint2D with 
     member this.X = x 
     member this.Y = y 

1番目の違いは、非常に目に見えるものですが、C#を使用すると、メンバーを実装契約のためにpublicと宣言する必要があります。

しかし、F#がプライベートメンバーとしてインターフェイスを実装できる理由は何ですか?センスは何ですか?

enter image description here

+4

"* C#を使用すると、メンバーをパブリックとして宣言する必要があります*" [明示的インターフェイスの実装(C#プログラミングガイド)](https://msdn.microsoft.com/en-us/library/ms173157.aspx) –

+0

@IvanStoevそれは別の方法です...あなたは明示的な実装を騙すことができます: 'IPoint2D pointObj = new Point2D();あなたはVStudio/VSCodeで試すかもしれません... –

+6

F#は暗黙のインターフェイスの実装をサポートしていません。あなたはアップキャストする必要があります: 'let p = firstPoint:> IPoint2D in pX' – krontogiannis

答えて

2

F#が直接自分のインターフェイスにアクセスするためにアップキャストするオブジェクトを必要とします。 let x = (firstPoint :> IPoint2D).X

F#は、関数パラメータの暗黙のインターフェイスキャストをサポートしています。それはジェネリックスを必要としましたが、新しいバージョンの言語で更新されています。

let Distance (a:IPoint2D) (b:IPoint2D) = 
    (a.X - b.X) * (a.X - b.X) + (a.Y - b.Y) * (a.Y - b.Y) 
    |> float |> Math.Sqrt 

let firstPoint = new Point2D(2, 3) 
let secondPoint = new Point2D(4, 5) 

let distance = Distance firstPoint secondPoint 
printf "%f" distance 

誰もが同意しているわけではありませんが、デザインルールとして、インターフェイスに直接アクセスするためにアップキャストするべきではありません。そうすると、コード結合が増加します。オブジェクト・インタフェース上のメソッドを呼び出すコードが記述されている場合、そのオブジェクト・クラスはすべてのコール・サイトを更新せずに簡単に変更することはできません。

インターフェイスがx、y、zのIPoint3Dで、IPoint2Dに変更したい場合は、距離のようなインターフェイスコンシューマだけでなく、zを参照するすべてのキャストを更新する必要があります。

私は、このデザインの選択が他の言語との一貫性のために行われたと信じており、OOPを使用している間に疎結合を促進しています。応答されていない暗黙のアップキャストを要求している2014年のuser voice feature requestがあります。

+0

非常に良い答え、ありがとう:) –

関連する問題