2016-09-04 8 views
2

Ich entschied mich, heute mit F # zu üben und fand eine interessante Sache. Ich werde den ähnlichen Code sowohl in C# und F # bieten, aber mit ziemlich unterschiedlichem Verhalten unter Verwendung von DAO (Data Access Object):F # Klasse implementiert Schnittstelle als privates Mitglied, warum?

C# Version:

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 # Version:

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 

Der 1. Unterschied, der sehr deutlich ist, dass mit C#, ich Mitglieder als public für die Umsetzung Vertrag erklären müssen.

Aber warum erlaubt F # die Schnittstelle als privates Mitglied zu implementieren? Was ist der Sinn?

enter image description here

+4

"* mit C#, ich muss Mitglieder als öffentlich deklarieren *" Nicht wirklich - [Explizite Schnittstellenimplementierung (C# -Programmierhandbuch)] (https://msdn.microsoft.com/en-us/library/ms173157.aspx) –

+0

@IvanStoev Es ist einfach anders ... Sie können die explizite Implementierung wie folgt austricksen: 'IPoint2D pointObj = new Point2D(); pointObj.X = 2; 'Sie können versuchen, in VStudio/VSCode ... –

+6

F # unterstützt keine implizite Schnittstellenimplementierung. Sie müssen umgestalten: 'lassen Sie p = firstPoint:> IPoint2D in pX' – krontogiannis

Antwort

2

F # erfordert Objekte upcast sein, um direkt auf ihre Schnittstellen zugreifen. let x = (firstPoint :> IPoint2D).X

F # unterstützt implizites Interface-Casting für Funktionsparameter. Früher wurde Generika benötigt, aber in neueren Versionen der Sprache wurde es aktualisiert.

Nicht alle stimmen zu, aber als Designregel sollten Objekte nicht direkt auf ihre Schnittstellen zugreifen. Dies erhöht die Code-Kopplung. Wenn Code geschrieben wird, der Methoden auf einer Objektschnittstelle aufruft, kann diese Objektklasse nicht einfach geändert werden, ohne alle Aufrufansichten zu aktualisieren.

Was wäre, wenn die Schnittstelle IPoint3D mit x, y, z wäre und Sie sie zu IPoint2D ändern wollten, müssten alle Umwandlungen, die z referenziert werden, anstatt nur Schnittstellenverbraucher wie Distance aktualisiert werden.

Ich glaube, dass diese Designwahl für Konsistenz mit dem Rest der Sprache gemacht wurde und lockere Kopplung während der Verwendung von OOP zu fördern. Es gibt eine user voice feature request von 2014, die unbeantwortet geblieben ist und implizites Upcasting verlangt.

+0

Sehr nette Antwort, danke :) –

Verwandte Themen