Tony
Tony

Reputation: 17637

What is the F# equivalent of this C# code?

I used VB.Net when I started in C# there was a code translating site. It would be good to have this for F#

I wrote this C# code

public interface IData : INotifyPropertyChanged
{
    Guid ID { get; set; }
}
public interface IVertex : INotifyPropertyChanged
{
}
public abstract class Vertex<IData>
{
    public IData Properties { get; set; }

    public Vertex()   {   }
    public Vertex(IData Properties)
    {
        this.Properties = Properties ;
    }

    public string Tipo { get { return typeof(IData).Name; } }
}
public class Data_Person : IData
{
    public event PropertyChangedEventHandler PropertyChanged;

    public Guid ID { get; set; } = Guid.NewGuid();
    public decimal Balance { get; set; }
    public string Name { get; set; }
}
public class Person : Vertex<Data_Person>, IVertex
{
    public Person()
    {
        this.Properties = new Data_Person();
    }
    public Person(Data_Person Properties) : base(Properties)
    {  }

    public event PropertyChangedEventHandler PropertyChanged;
}

public class EdgeLink<ISourceVertex, IEdgeData, ITargetVertex>
{
    public EdgeLink()
    {        }
    public EdgeLink(ISourceVertex In, IEdgeData Edge, ITargetVertex Out)
    {
        this.In = In;
        this.Properties = Edge;
        this.Out = Out;
    }

    public ISourceVertex In { get; set; }
    public IEdgeData Properties { get; set; }
    public ITargetVertex Out { get; set; }

    //public LoadStatus LoadStatus { get; set; } = LoadStatus.Uknown;
}

I am trying to do the same, but in F#.

How to 'translate' this to F# ?

I tried to translate, but it got messed, so far I have

type IData = 
    inherit INotifyPropertyChanged
    abstract member ID: Guid with get, set

type IEdgeData = 
    inherit IData

type IVertex =
    inherit INotifyPropertyChanged

type ISourceVertex =
    inherit IVertex

type ITargetVertex = 
    interface 
        inherit IVertex
    end

Upvotes: 0

Views: 409

Answers (1)

Aaron M. Eshbach
Aaron M. Eshbach

Reputation: 6510

Since the comments indicate that you're having trouble with the event and the generic type, here's how you would convert those, specifically:

open System
open System.ComponentModel

type IData =
    inherit INotifyPropertyChanged
    abstract member ID: Guid

type IVertex = inherit INotifyPropertyChanged

[<AbstractClass>]
type Vertex<'data when 'data :> IData> (properties: 'data) =
    member __.Properties = properties
    member __.Tipo = typeof<'data>.Name

type DataPerson (id, balance, name) =
    let propertyChanged = Event<_,_>()
    member __.ID = id
    member __.Balance = balance
    member __.Name = name
    interface IData with
        member __.ID = id
        [<CLIEvent>]
        member __.PropertyChanged = propertyChanged.Publish

You just need a generic type variable 'data constrained to be an IData for the Vertex class and an F# Event<_,_> with a [] property for the PropertyChanged event.

Note, I left out the setters on the properties here. You can easily add them back if you really need them.

EDIT

Adding the person class:

type Person (person) =
    inherit Vertex<DataPerson>(person)
    let propertyChanged = Event<_,_>()
    interface IVertex with
        [<CLIEvent>]
        member this.PropertyChanged = propertyChanged.Publish

EDIT 2

Adding optional parameters in constructors (I also made the Vertex.Properties property mutable this time, since it wouldn't make much sense to keep it immutable if you could instantiate the class with it uninitialized). I probably wouldn't do it this way in a pure-F# solution, but this is a more direct representation of the original C# code:

[<AbstractClass>]
type Vertex<'data when 'data :> IData> (?properties: 'data) =
    let vertexProperties = defaultArg properties Unchecked.defaultof<'data>
    member val Properties = vertexProperties with get,set
    member __.Tipo = typeof<'data>.Name

type DataPerson (id, balance, name) =
    let propertyChanged = Event<_,_>()
    member __.ID = id
    member __.Balance = balance
    member __.Name = name
    interface IData with
        member __.ID = id
        [<CLIEvent>]
        member __.PropertyChanged = propertyChanged.Publish

type Person (?person) =
    inherit Vertex<DataPerson>(defaultArg person Unchecked.defaultof<DataPerson>)
    let propertyChanged = Event<_,_>()     
    interface IVertex with
        [<CLIEvent>]
        member this.PropertyChanged = propertyChanged.Publish

Upvotes: 3

Related Questions