C# to F# class transition

三世轮回 提交于 2019-12-11 04:28:02

问题


I'm a C# dev since long ago.

I learn F# and use it for scientific purposes/research/approbation works. I find many its functional features powerful but I'm straggling to write classes — the essential thing I know to do very well in C#.

What would help me (and the community) is to translate the following C# code.

class CoolAttribute : Attribute
{
}

class BaseClass
{
    public BaseClass(int zzz)
    {
        // zzz doesn't matter; what matters is that zzz is required
    }

    public virtual void XHello()
    {
        Console.WriteLine("I'm BaseClass.");
    }
}

interface IFirst
{
    void Hello();
}

interface ISecond
{
    int MagicNumber();
}

[DebuggerDisplay("pubI = {pubI}")]
class SampleClass : BaseClass, IFirst, ISecond
{
    private int privI;
    protected int protI;
    public int pubI;

    private static string s_privStr;

    static SampleClass()
    {
        s_privStr = "";
    }

    public event Action<string> OnSomething = (el) => { };

    public int PubI
    {
        get { return pubI; }
        set { pubI = value; }
    }

    public static string StatStr
    {
        get { return s_privStr; }
    }

    // Default constructor
    SampleClass()
        : base(0)
    {
        privI = 1;
        protI = 2;
        pubI = 3;
    }

    // Other constructor
    SampleClass(int a, int b, int c)
        : base(a + b + c)
    {
        privI = a;
        protI = b;
        pubI = c;
    }

    [Conditional("DEBUG")]
    public void PubSimpleMethod()
    {
    }

    protected virtual void ProtVirtMethod()
    {
        OnSomething("From the virt method.");
    }

    private static void PrivStatMethod()
    {
    }

    public void Hello()
    {
        Console.WriteLine("Hello (IFirst)");
    }

    public override void XHello()
    {
        Console.WriteLine("I'm SampleClass");
    }

    public int MagicNumber()
    {
        return privI + protI + pubI;
    }

    public void Additional([Cool] int i)
    {
    }

    public static SampleClass operator +(SampleClass a, SampleClass b)
    {
        return new SampleClass(a.privI + b.privI,
            a.protI + b.protI,
            a.pubI + b.pubI);
    }
}

F# translation [work in progress, to be updated with answers]:

//// wrong ...
//type CoolAtribute =
//    extend Attribute

type BaseClass(zzz : int) =
    // virtual
    abstract XHello : unit -> unit
    default this.XHello() = 
        printfn "I'm BaseClass."

// seems Ok
type IFirst =
    abstract Hello : unit

type ISecond = 
    abstract MagicNumber : int

[<DebuggerDisplay("pubI = {pubI}")>] // ????
type SampleClass() =
    inherit BaseClass(0) // necessary argument ? 1 constructor
    // implements IFirst, ISecond

    let mutable privI = 0 // initialization required
    // protI
    // pubI

    // wrong:
    //let static mutable s_privStr = ""

    // static constructor

    // event OnSomething

    // seems Ok
    member this.PubI
        with get() = privI
        and  set(value) = privI <- value

    // ??
    //static member StatStr
    //    with get() = s_privStr
    //    and  set(value) = s_privStr <- value


    // Default constructor


    // Other constructor
    // C#: SampleClass(int a, int b, int c)

    [<Conditional("DEBUG")>]
    member this.PubSimpleMethod() =
        do ignore

    abstract ProtVirtMethod : unit -> unit
    //protected 
    default this.ProtVirtMethod() =
        // raise event OnSomething("From the virt method.");

    //private
    //static
    member this.PrivStatMethod() =
        do ignore

    member this.Hello() =
        printfn "Hello (IFirst)"

    // override 
    member this.XHello() =
        printfn "I'm SampleClass"

    member this.MagicNumber() : int =
        privI + protI + pubI

    // apply attribute to the argument
    member this.Additional( (*[Cool*) i :int) =
        do ignore

    // operator +

回答1:


Most of the code looks good to me, but you can't use plain member to define virtual methods. (This is because F# code does not typically use implementation inheritance, so this is not needed that often).

To define a virtual method, you need to use abstract and default:

type Virtual() = 
  abstract Foo : int -> int
  default this.Foo(n) = n + 1

To override the method in a derived type, you can write:

type Derived() =
  inherit Virtual()

  override this.Foo(n) = n + 2    


来源:https://stackoverflow.com/questions/7901510/c-sharp-to-f-class-transition

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!