简体   繁体   English

C#到F#类的过渡

[英]C# to F# class transition

I'm a C# dev since long ago. 我很久以前是C#开发人员。

I learn F# and use it for scientific purposes/research/approbation works. 我学习F#,并将其用于科学目的/研究/认可工作。 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#. 我发现它的许多功能强大,但是我却在努力编写类-我知道在C#中做得很好的本质。

What would help me (and the community) is to translate the following C# code. 对我(和社区)有帮助的是翻译以下C#代码。

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]: F#翻译[正在进行中,有待更新]:

//// 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 +

Most of the code looks good to me, but you can't use plain member to define virtual methods. 大多数代码对我来说看起来不错,但是您不能使用普通member来定义虚拟方法。 (This is because F# code does not typically use implementation inheritance, so this is not needed that often). (这是因为F#代码通常不使用实现继承,因此通常不需要这样做)。

To define a virtual method, you need to use abstract and default : 要定义虚拟方法,您需要使用abstractdefault

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    

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM